C++ 已经拥有了拷贝构造函数, 和赋值函数,它们主要定位为浅和深度拷贝, 新增加一个移动构造函数,主要避免拷贝构造。
在定义了移动构造函数的情况下,在实参(argument)是一个右值(rvalue,包括xvalue和prvalue)的情况下会调用移动构造函数,而不是调用复制构造函数
可以使用std::move语句可以将左值变为右值而避免拷贝构造,修改代码如下:
编译器会对返回值进行优化,简称RVO,是编译器的一项优化技术,它涉及(功能是)消除为保存函数返回值而创建的临时对象。
-fno-elide-constructors,此选项作用是,在 g++ 上编译时关闭 RVO。
shell> g++ main.cpp -std=c++11 -fno-elide-constructors
#include <iostream>
using namespace std;
class Test
{
public:
Test(int a = 0)
{
d = new int(a);
cout << "cs" << this <<endl;
}
Test(const Test & tmp)
{
d = new int;
*d = *(tmp.d);
cout << "copy\n";
}
// Test(Test && tmp)
// { // 移动构造函数
// d = tmp.d;
// tmp.d = NULL; // 将临时值的指针成员置空
// cout << "mv" << this << endl;
// }
~Test()
{
if(d != NULL)
{
delete d;
cout << "delete d\n";
}
cout << "ds: " << this << endl;
}
int * d;
};
Test GetTmp()
{
Test h;
cout << "Resource from " << __func__ << ": " << (void *)h.d << endl;
return h;
}
int main()
{
//Test&& obj = GetTmp();
Test obj = GetTmp();
cout << "Resource from " << __func__ << ": " << (void *)obj.d << endl;
return 0;
}
使用移动语义后
#include <iostream>
using namespace std;
class Test
{
public:
Test(int a = 0)
{
d = new int(a);
cout << "cs" << this <<endl;
}
Test(const Test & tmp)
{
d = new int;
*d = *(tmp.d);
cout << "copy\n";
}
Test(Test && tmp)
{ // 移动构造函数
d = tmp.d;
tmp.d = NULL; // 将临时值的指针成员置空
cout << "mv" << this << endl;
}
~Test()
{
if(d != NULL)
{
delete d;
cout << "delete d\n";
}
cout << "ds: " << this << endl;
}
int * d;
};
Test GetTmp()
{
Test h;
cout << "Resource from " << __func__ << ": " << (void *)h.d << endl;
return h;
}
int main()
{
Test&& obj = GetTmp();
cout << "Resource from " << __func__ << ": " << (void *)obj.d << endl;
return 0;
}
int main()
{
//Test&& obj = GetTmp();
Test obj = GetTmp();
cout << "Resource from " << __func__ << ": " << (void *)obj.d << endl;
return 0;
}