先看個代碼吧!!!!!!!!!!
#include <iostream> using namespace std; class A { public: A(){cout<<"construct1..............."<<endl;} A& operator = (const A&&) {cout<<" operator move"<<endl;} A(const A&&){cout<<"move construct "<<endl;} A& operator = (const A&){cout<<"copy operator"<<endl;} A(const A&){cout<<"copy construct"<<endl;} }; int main() { A a1 = A(); // 這里調用的到底是哪一個構造函數? A a2 = std::move(A()); // 調用什么呢? a2 = A();//調用operator =(const A&&) A&& a = A();//只調用默認構造 return 0; }
$g++ -std=c++11 -o main *.cpp -fno-elide-constructors 去掉優化
$main
construct1............... move construct construct1............... move construct construct1............... operator move construct1...............
上面的代碼如果注釋掉9行10行結果如下
$g++ -std=c++11 -o main *.cpp -fno-elide-constructors 去掉優化
$main
construct1...............
copy construct
construct1...............
copy construct
construct1...............
copy operator
construct1...............
上面的代碼正好驗證了一句話 定義了move構造函數后,拷貝構造函數默認為刪除的。 不刪除也不會有什么影響!!!(目前是這樣)
effective modern cpp 條款17 理解特殊成員函數的生成規則
你要記住的事
- 特殊成員函數是那些編譯器可能自己幫我們生成的函數:默認構造函數,析構函數,copy操作,move操作。
- 只有在類中沒有顯式聲明的move操作,copy操作和析構函數時,move操作才被自動生成。
- 只有在類中沒有顯式聲明的拷貝構造函數的時候,拷貝構造函數才被自動生成。只要存在move操作的聲明,拷貝構造函數就會被刪除(delete)。拷貝operator=和拷貝構造函數的情況類似。在有顯式聲明的copy操作或析構函數時,另一個copy操作能被生成,但是這種生成方法是被棄用的
- 成員函數模板永遠不會抑制特殊成員函數的生成。
還未學完!!!!!!!!