2010-08-05 47 views
1

鑑於類:什麼時候會調用ctor?

class C 
{ 
public: 
    C() 
    { 
     cout << "Dflt ctor."; 
    } 
    C(C& obj) 
    { 
     cout << "Copy ctor."; 
    } 
    C(C&& obj) 
    { 
     cout << "Move ctor."; 
    } 
    C& operator=(C& obj) 
    { 
     cout << "operator="; 
     return obj; 
    } 
    C& operator=(C&& obj) 
    { 
     cout << "Move operator="; 
     return obj; 
    } 
}; 

,然後在主:

int main(int argc, char* argv[]) 
{ 
    C c; 
    C d = c; 
    C e; 
    e = c; 
    return 0; 
} 

因爲你會從輸出看到「常規」拷貝構造函數和operator=的版本被調用,但不是那些與右值ARGS。所以我想問一下在什麼情況下可以調用ctor和operator=(C&&)

回答

7

移動構造函數將在右邊是臨時的時候被調用,或者使用static_cast<C&&>std::move明確地轉換爲C&&

C c; 
C d(std::move(c)); // move constructor 
C e(static_cast<C&&>(c)); // move constructor 
C f; 
f=std::move(c); // move assignment 
f=static_cast<C&&>(c); // move assignment 
C g((C())); // move construct from temporary (extra parens needed for parsing) 
f=C(); // move assign from temporary 
1

IIRC,您必須使用C d = std::move(c)來使用移動構造函數。

一個例子未經測試,但可能更好地解釋使用移動構造函數的:

C&& foo() { C c; return std::move(c); } 
1
std::swap(c,e); // c and e variables declared in your _tmain() 

將調用移動的構造。

1

所有變量都是左值,因此不能隱式移動,因爲您可能需要稍後訪問它們。另外,複製構造函數和賦值運算符需要const引用。

右值引用適用於右值,即臨時對象。爲了看到使用的移動構造函數,首先,你將不得不實際創建一個臨時對象。另外,不要忘記RVO仍然適用,並且可能會釘住任何或所有std :: cout調用。

你可以使用std :: move(lvalue)從左值創建一個右值。

-1

使用移動運營商的更現實的例子是,如果你有返回對應c & &本地棧上創建這樣一個靜態類:

static C&& CreateC() 
{ 
    C c(); 
    //do something with your object 
    return c; 
} 

,然後調用它像這樣:

C x = CreateC(); // move operator is invoked here 
+0

請在投票時發表評論 – 2016-05-04 20:08:16

相關問題