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进去就行 ...
随机推荐
- 一般处理程序获取session值
1.要在一般处理程序中获取其他页面的session值,需要引用名空间: using System.Web.SessionState; 2.然后继承一个接口:IRequiresSessionState, ...
- volatile关键字与线程间通信
>>Java内存模型 现在计算机普遍使用多处理器进行运算,并且为了解决计算机存储设备和处理器的运算速度之间巨大的差距,引入了高速缓存作为缓冲,缓存虽然能极大的提高性能,但是随之带来的缓存一 ...
- Delphi线程同步(临界区、互斥、信号量)
当有多个线程的时候,经常需要去同步这些线程以访问同一个数据或资源. 例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于统计文件的字符数.当然,在整个文件调入内存之前,统计它的计数是 ...
- 网站对话框开源脚本--ArtDialog V6.0
初识对话框脚本觉得artDialog还是挺不错的开源的js脚本,最新版本都是V6.0 ,相对之前版本,artDialog的语法也发生很大的变化,windows对应的JS版本如下 点击下载 语法也发生变 ...
- C#调用ArcGIS REST服务
ArcGIS REST API提供了简单.开放的接口来访问和使用ArcGIS Server发布的服务.使用ArcGIS REST API通过URL可以获取和操作每一个服务中的所有资源和操作. 1.使用 ...
- mysql 查询优化规则
.请不要在SELECT中使用DISTINCT: #会用到临时表 .尽可能不要SELECT *,而应该查询需要用到的指定几个字段: .不要对两个大表进行联合,无论是内联或外联.对于需要对两个或多个表进行 ...
- phpMailer在thinkPHP框架中邮件发送
资源下载地址:http://pan.baidu.com/s/1c0kAoeO 提取码:ry5v 关键代码:application/Common/Common/funciton.php <?php ...
- apk 打包方式
1 项目-->Android tools -->Export Signed Application Package 2 在项目 manifest.xml文件下 单击“use the Ex ...
- sqlserver 作业调度(作业常用的几个步骤)
--[作业常用的几个步骤] EXEC msdb.dbo.sp_delete_job EXEC msdb.dbo.sp_add_job EXEC msdb.dbo.sp_add_jobstep EXEC ...
- LoadRunner 接口测试
Action1() { int i; lr_rendezvous("rend"); lr_start_transaction("get"); ;i<;i+ ...