2016-09-02 98 views
17

我想實現一個沒有複製構造函數的類的移動構造函數。我得到一個錯誤,該類的成員的默認構造函數丟失。爲什麼移動構造函數需要其成員的默認構造函數?

這裏有一個簡單的例子來說明這一點:

struct A { 
public: 
     A() = delete; 
     A(A const&) = delete; 
     A(A &&a) {} 
}; 

struct B { 
     A a; 
     B() = delete; 
     B(B const&) = delete; 
     B(B &&b) {} 
}; 

嘗試編譯,我得到:

move_without_default.cc: In constructor ‘B::B(B&&)’: 
move_without_default.cc:15:11: error: use of deleted function ‘A::A()’ 
    B(B &&b) {} 
     ^
move_without_default.cc:6:2: note: declared here 
    A() = delete; 
^

爲什麼這是一個錯誤?任何方式呢?

+8

用'= default'替換'{}';' – cpplearner

+0

因爲'A'的默認構造函數被刪除,但'B'使用它。 – tkausl

+6

空移動構造函數不會自動嘗試執行逐個成員的移動。你的移動構造函數試圖默認構造'a',而不是移動 - 構造它。 – user2357112

回答

17

使用構造函數的初始值設定項列表初始化A成員。按照書面的說法,移動構造函數使用(如編譯器所說的)A的默認構造函數。

B(B&& b) : a(std::move(b.a)) {} 
9

移動構造函數通常不需要提供默認的初始化。 您的移動構造函數確實。

移動構造函數仍然是一個構造函數。因此,它必須初始化所有子對象。如果你沒有提供顯式初始化,那麼它會嘗試默認初始化它們。如果它不能這樣做,你會得到一個錯誤。

因此,您可以初始化它們(可能從b移動),也可以將= default用於移動構造函數,並讓編譯器完成它的工作。

23

爲什麼移動構造函數需要其成員的默認構造函數?

此舉構造您定義默認構造一個成員。如果您默認構造任何成員,那麼這些成員需要缺省構造函數。

構造函數(無論是常規,複製還是移動)默認初始化未在成員初始化列表中列出的成員,也不具有默認成員初始化。 B::a不在移動構造函數的成員初始化列表中(它根本沒有初始化列表),並且沒有默認成員初始化。

任何方式嗎?

最簡單,使用默認的移動構造函數:

B(B&&) = default; 

默認轉移構造布展構建成員。

相關問題