C++11 feature: move constructor
There are heaps of good articles out there about C++ features including this move constructor. However this one focuses on this feature helping resolve a drawback with the C++'s costly value return that has long been annoying me.
Let's have a look at the following code excerpt,
#include <cstring>
#include <utility> class A
{
char *_innerData; public:
A() : _innerData(NULL)
{
} ~A()
{
if (_innerData)
{
delete[] _innerData;
}
} A(char *pszData)
{
int buflen = strlen(pszData)+1;
_innerData = new char[buflen];
strcpy(_innerData, pszData);
} A(const A& other)
{
int buflen = strlen(other._innerData)+1;
_innerData = new char[buflen];
strcpy(_innerData, other._innerData);
} A(A&& other)
{
_innerData = other._innerData;
other._innerData = NULL;
} A& operator=(const A&other)
{
_innerData = new char[strlen(other._innerData)+1];
strcpy(_innerData, other._innerData);
return (*this);
} public:
char *GetData()
{
if (_innerData == NULL) return "<null>";
return _innerData;
} public:
static A ModA(const A &origin)
{
A modified = origin;
char *pOldData = modified._innerData;
modified._innerData = new char[strlen(pOldData)+4];
strcpy(modified._innerData, pOldData);
strcat(modified._innerData, "abc");
delete[] pOldData;
return modified;
}
};
If we call the ModA method as below, normally we expect the value to be copied at least once from the top stack frame to the target value and the copy constructor is invoked.
A a("haha i'm the first");
A d = A::ModA(a);
printf("d = %s\n", d.GetData());
As far as there's a move constructor, the compiler enforces the move constructor being called upon the return of the suburoutine (it makes sense as the local variable will not be used) which makes the value transfer more efficient.
Lets step gack to thinking about the copy constructor. It is inefficient in this case, however it's not impossible to implemebt a shallow copy. However this is not a safe and good pratice as the user might use it assuming it's deep copy and encounter error upon deallocation. That's why move constructor comes in as a memory safe solution.
Note it only works with this pattern, defining a reference type (A& or even A&&) in this case doesn't help and is even invalid, and providing a value through a parameter of a reference type doesn't require this technique.
In general this entire new feature only helps avoid unnecessary deep copy of large internal objects on dynamically allocated memory, it doesn't eliminate copying of statically existing members since it's not a reference/pointer to the whole object.
C++11 feature: move constructor的更多相关文章
- C++11之 Move semantics(移动语义)(转)
转https://blog.csdn.net/wangshubo1989/article/details/49748703 按值传递的意义是什么? 当一个函数的参数按值传递时,这就会进行拷贝.当然,编 ...
- [C++] decltype(auto) C++ 11 feature
1 //C++ 11 feature template <class T1, class T2> auto getMultiply(T1 data1, T2 data2) -> de ...
- stout代码分析之十:c++11之move和forward
stout中大量使用了c++11的特性,而c++11中move和forward大概是最神奇的特性了. 左值和右值的区别 ; // a是左值,0是右值 int b = rand(); // b是左值,r ...
- 右值引用、move与move constructor
http://blog.chinaunix.net/uid-20726254-id-3486721.htm 这个绝对是新增的top特性,篇幅非常多.看着就有点费劲,总结更费劲. 原来的标准当中,参数与 ...
- C++11 std::move和std::forward
下文先从C++11引入的几个规则,如引用折叠.右值引用的特殊类型推断规则.static_cast的扩展功能说起,然后通过例子解析std::move和std::forward的推导解析过程,说明std: ...
- c++11 std::move()
简单点理解,c++11 中的std::move() 函数,实际上就是将一个左值强制转换成一个右值引用数据类型,从而可以调用相应的对右值引用重载的函数. 如果使用std::move() 的返回值做为参数 ...
- c++11 std::move() 的使用
std::move函数可以以非常简单的方式将左值引用转换为右值引用.(左值.左值引用.右值.右值引用 参见:http://www.cnblogs.com/SZxiaochun/p/8017475.ht ...
- 重构改善既有代码设计--重构手法11:Move Field (搬移字段)
你的程序中,某个字段被其所驻类之外的另一个类更多的用到.在目标类建立一个新字段,修改源字段的所有用户,令它们改用新字段. 动机:在类之间移动状态和行为,是重构过程中必不可少的措施.随着系 ...
- C/C++ C++ 11 std::move()
{ 0. C++ 标准库使用比如vector::push_back 等这类函数时,会对参数的对象进行复制,连数据也会复制.这就会造成对象内存的额外创建, 本来原意 是想把参数push_back进去就行 ...
随机推荐
- 写了个简单的pdo的封装类
<?php class PD { //造对象 public $dsn = "mysql:dbname=test2;host=localhost"; //数据库类型,数据库名和 ...
- C#集合类型
using System; using System.Collections; using System.Collections.Generic; namespace codeTest { class ...
- 无题- Anyway,Object-C
Json String Body see here: working-with-json-in-ios-5also see here: serialize-custom-object-to-json- ...
- java中的负数的问题
在计算机中是使用二制数中的最高位表示来正负. 二进制的储存中都是用的补码,正数的原码.反码和补码相同,负数的原码是最高位为1,反码最高位不变,其余各位取反,补码为其反码+1(重要!!) 首先得知道最高 ...
- java集群技术(转)
来源:http://blog.csdn.net/cdh1213/article/details/21443239 序言 越来越多的关键应用运行在J2EE(Java2, Enterprise Editi ...
- 【jQuery 区别】.click()和$(document).on("click","指定的元素",function(){});的区别
给出以下的代码展示: //绑定 下一页 的点击事件 $("a[aria-label='Next']").click(function(){ $("a[aria-label ...
- kylin学习笔记
阅读官网,学到哪就写到哪 1.需要先建立Model 2.kylin需要配置事实表,纬度表:可以自定义join. 我的用法和官方建议的不同,我是直接在hive中将所有的取join成一个单表,再根据单表 ...
- [转载]explicit关键字
本文转自http://www.programlife.net/cpp-explicit-keyword.html. 其实explicit主要用于防止隐式转换,用于修饰构造函数.复制构造函数[注意:一般 ...
- 廖雪峰js教程笔记5 Arrow Function(箭头函数)
为什么叫Arrow Function?因为它的定义用的就是一个箭头: x => x * x 上面的箭头函数相当于: function (x) { return x * x; } 箭头函数 阅读: ...
- DSP using MATLAB 示例 Example3.12
用到的性质 代码: n = -5:10; x = sin(pi*n/2); k = -100:100; w = (pi/100)*k; % freqency between -pi and +pi , ...