浅复制(默认、复制构造函数,赋值操作符重载):当涉及到动态内存时,不安全; 深复制(默认、复制构造函数,赋值操作符重载):当涉及到动态内存时,安全; 移动语义(移动构造函数,移动赋值操作符重载):一种特殊的浅复制定义(右值引用),用来避免不必要的副本机制和临时对象的创建与删除。 要实现移动语义,需要采取某种方式,让编译器知道什么时候需要复制,什么时候不需要。这就是右值引用发挥作用的地方。可定义两个构造函数。其中一个是常规复制构造函数,它使用const左值引用作为参数,这个引用关联到左值实参;另一个是移动构造函数,它使用右值引用作为参数,该引用关联到右值实参。复制构造函数可执行深复制,而移动构造函数只调整记录。在将所有权转移给新对象的过程中,移动构造函数可能修改其实参,这意味着右值引用参数不应 是const。 代码:// stdmove.cpp -- using std::move() #include#include // use the following for g++4.5 // #define nullptr 0 // interface class Useless { private: int n; // number of elements char * pc; // pointer to data static int ct; // number of objects void ShowObject() const; public: Useless(); explicit Useless(int k); Useless(int k, char ch); Useless(const Useless & f); // regular copy constructor Useless(Useless && f); // move constructor ~Useless(); Useless operator+(const Useless & f)const; Useless & operator=(const Useless & f); // copy assignment Useless & operator=(Useless && f); // move assignment void ShowData() const; }; // implementation int Useless::ct = 0; Useless::Useless() { ++ct; n = 0; pc = nullptr; } Useless::Useless(int k) : n(k) { ++ct; pc = new char[n]; } Useless::Useless(int k, char ch) : n(k) { ++ct; pc = new char[n]; for (int i = 0; i < n; i++) pc[i] = ch; } Useless::Useless(const Useless & f): n(f.n) { ++ct; pc = new char[n]; for (int i = 0; i < n; i++) pc[i] = f.pc[i]; } Useless::Useless(Useless && f): n(f.n) { ++ct; pc = f.pc; // steal address f.pc = nullptr; // give old object nothing in return f.n = 0; } Useless::~Useless() { delete [] pc; } Useless & Useless::operator=(const Useless & f) // copy assignment { std::cout << "copy assignment operator called: "; if (this == &f) return *this; delete [] pc; n = f.n; pc = new char[n]; for (int i = 0; i < n; i++) pc[i] = f.pc[i]; return *this; } Useless & Useless::operator=(Useless && f) // move assignment { std::cout << "move assignment operator called: "; if (this == &f) return *this; delete [] pc; n = f.n; pc = f.pc; f.n = 0; f.pc = nullptr; return *this; } Useless Useless::operator+(const Useless & f)const { Useless temp = Useless(n + f.n); for (int i = 0; i < n; i++) temp.pc[i] = pc[i]; for (int i = n; i < temp.n; i++) temp.pc[i] = f.pc[i - n]; return temp; } void Useless::ShowObject() const { std::cout << "Number of elements: " << n; std::cout << " Data address: " << (void *) pc << std::endl; } void Useless::ShowData() const { if (n == 0) std::cout << "(object empty)"; else for (int i = 0; i < n; i++) std::cout << pc[i]; std::cout << std::endl; } // application int main() { using std::cout; { Useless one(10, "x"); Useless two = one +one; // calls move constructor cout << "object one: "; one.ShowData(); cout << "object two: "; two.ShowData(); Useless three, four; cout << "three = one "; three = one; // automatic copy assignment cout << "now object three = "; three.ShowData(); cout << "and object one = "; one.ShowData(); cout << "four = one + two "; four = one + two; // automatic move assignment cout << "now object four = "; four.ShowData(); cout << "four = move(one) "; four = std::move(one); // forced move assignment cout << "now object four = "; four.ShowData(); cout << "and object one = "; one.ShowData(); } std::cin.get(); } 通过提供一个使用左值引用的构造函数和一个使用右值引用的构造函数,将初始化分成了两组。 使用左值对象初始化对象时,将使用复制构造函数,而使用右值对象初始化对象时,将使用移动构造函数。 程序员可根据需要赋予这些构造函数不同的行为。 ref StephenPrata:《C++ Primer Plus(6th 2011)》 -End-