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进去就行 ...
随机推荐
- How many Fibs?【sudt 2321】【大数的加法及其比较】
How many Fibs? Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 Recall the definition of t ...
- Win10 for Phone 裁剪保存
//StorageFolder savedPics = ApplicationData.Current.LocalFolder; //BitmapImage bi = new BitmapImage( ...
- PHP实现上一篇、下一篇
//php实现上一篇.下一篇 获取当前浏览文章id $id = isset($_GET[ ? intval($_GET['id']) : ""; 下一篇文章 $query = my ...
- AgileEAS.NET SOA 中间件平台 5.2 发布说明-包含Silverlight及报表系统的开源代码下载
一.AgileEAS.NET SOA 中间件简介 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速 ...
- WPF 自定义Metro Style窗体
为了使WPF程序在不同版本的操作系统上保持一致的显示效果,我们需要重写WPF控件样式.这篇博客将展示如何创建一个Metro Style的WPF窗体. 首先先看一下最终窗体的效果图, 通过截图我们可以看 ...
- jbox使用总结
jbox是一个不错的插件 当使用get打开新页面的时候,可以使用h.对像ID来获得对像ID的值 Js代码 js代码: /** * @description: test * @author: BrinP ...
- 【JS】两种计时器/定时器
1.首先介绍定时器 定时器:设置一个定时器,再设置一个等待的时间,到达指定时间后,执行对应的操作 两种定时器:用法一样,区别一个执行后不会停下来,一个只执行一次 第一种:window.setInter ...
- go语言
Go语言是谷歌推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性.和今天的C++或C一样,Go是一种系统语言. 1.windows开发工具:Golang for Windows ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- Webbrowser中显示MHT文件
把MHT文件存成临时文件,用WEBBROWSER的Navigate方法打开,代码如下: //从程序集中读取资源文件 Assembly asmm = Assembly.GetCallingAssembl ...