在閱讀有關move constructor從目前standard,我可以看到以下這一點:瞭解默認移動構造函數定義
12.8複製和移動類對象
如果一個類的定義X沒有明確聲明一個移動構造函數,只有當且僅當
- X沒有用戶聲明的複製構造函數,
- X沒有用戶聲明的複製賦值運算符,
- X沒有用戶聲明的移動賦值運算符,並且
- X沒有用戶聲明的析構函數。[注意:當移動構造函數未被隱式聲明或顯式提供時,否則將調用移動構造函數的表達式可能會調用複製構造函數。 - 結束注意]
我覺得注意部分清楚地提到,默認移動構造函數的後退將是複製構造函數。爲了理解這個概念,我編寫了一個小程序來理解這個概念。
#include<iostream>
struct handleclass {
public:
handleclass():length{0}, p{nullptr} {}
handleclass(size_t l):length{l},p{new int[length]} { }
~handleclass() { delete[] p; }
size_t length;
int* p;
};
handleclass function(void) {
handleclass x(10);
return x;
}
int main() {
handleclass y;
std::cout<<y.length<<std::endl;
y = function();
std::cout<<y.length<<std::endl;
handleclass a;
handleclass b(10);
a = std::move(b);
return 0;
}
顯然這個方案是不正確,將由兩個對象有不確定的操作(終止)由於資源的淺拷貝。但我的重點是瞭解程序中生成和使用的默認移動構造函數。我希望這個例子有意義。
在上面的程序中,在移動構造函數應該被調用的兩種情況下,在我看來,編譯器正在使用默認的拷貝構造函數。
根據標準中提到的上述規則,我認爲我們應該得到編譯器錯誤,因爲現在程序顯式地嘗試調用移動構造函數,並且用戶既沒有執行也沒有編譯器生成默認(隱式),如上面的規則不滿足?。
但是,這是得到編譯沒有任何警告/錯誤,併成功運行。有人可以解釋有關默認(隱式)移動構造函數的概念嗎?或者我錯過了什麼?
-fno-elide-constructors選項可用於禁用g ++的複製elision – 2014-10-07 02:01:16