我新的C++ 11和寫了下面的代碼來了解std::move
是如何工作的:瞭解移動構造函數,的std ::移動和析構函數
#include <queue>
#include <stdio.h>
class X {
public:
X(int x) : x_(x) {}
~X() {
printf("X(%d) has be released.\n", x_);
}
X(X&&) = default;
X& operator = (X&&) = default;
X(const X&) = delete;
X& operator = (const X&) = delete;
private:
int x_;
};
int main() {
std::queue<X> xqueue;
for (int x = 0; x < 5; ++x) {
xqueue.push(std::move(X(x)));
}
return 0;
}
但是,它會生成以下的輸出,這表明每個X(n)
的析構函數已被調用兩次:
X(0) has be released.
X(1) has be released.
X(2) has be released.
X(3) has be released.
X(4) has be released.
X(0) has be released.
X(1) has be released.
X(2) has be released.
X(3) has be released.
X(4) has be released.
我可以想像第二輪的輸出發生在右功能main()
的端部,並且所述第一輪可能發生在循環時,這些中間X
超出範圍。
但是,我認爲這樣的中間產品X
的所有權將完全轉移到隊列中,並且不應在其所有權轉移期間調用它們的析構函數。
所以我的問題是:
- 當我看到被釋放兩次的情況下,這是否意味着它執行復制而不是移動?
- 如果上面的答案是肯定的,那麼我怎樣才能真正避免複製?
謝謝
因此,如果我的對象有成員指針,並且它的析構函數將釋放這些指針。這是否意味着我無法真正移動這些對象? – keelar
@keelar你可以 - 當你從它移動時,只需設置指向'nullptr'的指針。在空指針上執行delete操作將不起作用。在實現移動構造函數/賦值運算符時,應該使對象保持有效(但不確定)狀態。 –
非常感謝!這聽起來很完美。我能否進一步知道'= default'移動構造函數/賦值是否將'nullptr'賦值給源成員指針?或者我應該開發自己的移動構造函數/任務? – keelar