C++ 已经拥有了拷贝构造函数, 和赋值函数,它们主要定位为浅和深度拷贝, 新增加一个移动构造函数,主要实现一个选择性重用临时对象。
在定义了移动构造函数的情况下,在实参(argument)是一个右值(rvalue,包括xvalue和prvalue)的情况下会调用移动构造函数,而不是调用复制构造函数
编译器会对返回值进行优化,简称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; }