2013-04-30 109 views
9

我有一個類,PlayerInputComponent這是爲什麼調用複製構造函數,而不是移動構造函數?

.H:

class PlayerInputComponent 
{ 
public: 
    PlayerInputComponent(PlayerMoveComponent& parentMoveComponent_, std::unique_ptr<IRawInputConverter> inputConverter_); 
    PlayerInputComponent(PlayerInputComponent&& moveFrom); 
    void update(); 

private: 
    std::unique_ptr<IRawInputConverter> inputConverter; 
    PlayerMoveComponent& parentMoveComponent; 
}; 
} 

的.cpp:

PlayerInputComponent::PlayerInputComponent(PlayerMoveComponent& parentMoveComponent_, std::unique_ptr<IRawInputConverter> inputConverter_) : 
    parentMoveComponent(parentMoveComponent_), 
    inputConverter(std::move(inputConverter_)) 
{ 
} 

PlayerInputComponent::PlayerInputComponent(PlayerInputComponent&& moveFrom) : 
    parentMoveComponent(moveFrom.parentMoveComponent), 
    inputConverter(moveFrom.inputConverter.release()) 
{ 
} 

和一個類,PlayerMoveComponen噸,包含PlayerInputComponent構件和使用初始化std::unique_ptr作爲參數傳遞。它的構造:

PlayerMoveComponent::PlayerMoveComponent(/* other parameters */ std::unique_ptr<IRawInputConverter> inputConverter) : 
    //other initializations 
    inputComponent(PlayerInputComponent(*this, std::move(inputConverter))) 
{ 
} 

我定義我自己的移動構造函數以來我理解PlayerInputComponent類是默認的移動構造函數將不會被用於構建包含一個引用成員的類。在這種情況下,儘管我知道該參考將在PlayerInputComponent對象的生命週期的範圍內保持在範圍內。

由於我初始化PlayerMoveComponent「從臨時小號inputComponent變量,我認爲以下兩件事情之一是應該發生:

  1. PlayerInputComponent的舉動構造函數用於初始化playerInputComponent成員變量。
  2. 這一舉措被編譯器忽略了。

然而,的Visual Studio 2012吐出了這一點:

error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' 
1>   with 
1>   [ 
1>    _Ty=SDLGame::IRawInputConverter 
1>   ] 
1>   c:\program files\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr' 
1>   with 
1>   [ 
1>    _Ty=SDLGame::IRawInputConverter 
1>   ] 
1>   This diagnostic occurred in the compiler generated function 'PlayerInputComponent::PlayerInputComponent(const PlayerInputComponent &)' 

爲什麼拷貝構造函數在這裏被稱爲?使PlayerInputComponent類的parentMoveComponent成員成爲一個常規的ParentMoveComponent實例,而不是引用,可以擺脫該錯誤,但我不明白爲什麼 - 我測試並驗證了,只要您提供了參考成員就可以使用參考成員移動構造對象自己的移動構造函數,那麼交易是什麼?

+0

@MooingDuck:我看不出如何回答這個問題。我很確定這是MSVC中的一個錯誤。 – 2013-05-01 00:03:47

+1

@JesseGood:[哦你是對的](http://coliru.stacked-crooked.com/),我誤解了部分代碼。然後它是[我的這個錯誤報告](https://connect.microsoft。com/VisualStudio/feedback/details/778513/msvc10-using-copy-constructor-instead-of-move):P – 2013-05-01 00:15:05

+0

上述類的*聲明*被分解爲只包含可重複的結果特別是'PlayerMoveComponent' – WhozCraig 2013-05-01 00:25:40

回答

1

對不起,如果這不能真正回答你的問題,我只想對你的問題的表面複雜性作出反應。如果可以的話,千萬不要這麼簡單:

/********************  **********  ********************/ 

class C {}; 
class B; 



class A 
{ 
public: 

    A(): _b(nullptr), _c(nullptr) {} 
    A(B *b, C *c): _b(b), _c(c) {} 
    A(A&& a): _b(a._b), _c(a._c) {} 

private: 

    C *_c; 
    B *_b; 
}; 



class B 
{ 
public: 

    B(/* other parameters */ C *c): _a(A(this,c)) {} 

private: 

    A _a; 
}; 


    /********************  **********  ********************/ 


int main() 
{ 
    C c; 
    B b(&c); 
} 

然而實現同樣的事情呢?我沒有反對在C++ 11中使用新功能,如std::unique_ptr,但恕我直言,確保指針永遠不能從兩個地方解除引用不應該是運行時檢查的問題(除非可能在極少數情況下),但設計的問題..不應該嗎?

+0

我真的同意你的看法,但我認爲不使用原始指針的主要原因是對誰使用原始指針有一定的安全性。例如在你的代碼中,我可以傳遞一個c指針給你的B類,並且在這個調用之後刪除它! (BOOM ...稍後會崩潰)。如上所述使用unique_ptr可以防止這種情況發生,因爲控制權將傳遞給新的B實例,並且沒有人可以刪除它。 – 2013-05-07 21:34:47

+0

Ahn ...順便說一句,我不知道是否unique_ptr在解引用時做任何類型的檢查...如果你創建一個全新的(nullptr)並嘗試訪問它,它將像任何指針一樣崩潰。當你想要確定誰是所有者時它是有用的,並且它必須是一個所有者(唯一)。 – 2013-05-07 21:38:49

+0

@JulioRaffaine非常感謝這些評論!:)我的意思是解除引用是這個;你想要一個'unique_ptr'的唯一原因是你不想讓其他人訪問它。 AFA的刪除關注,足夠有趣,我認爲它應該更簡單,如果你打算使用'unique_ptr',並且你最終不會:這裏唯一包含唯一c指針的類是A,所以邏輯上應該是A在析構函數中刪除爲c分配的內存,並在它被簡單複製時將其「取消」。 – Sheljohn 2013-05-07 21:53:02

1

如果使用=初始化新對象,默認情況下會觸發複製構造函數。 要觸發移動構造函數,你需要改變operator=的行爲 你可以找到一個例子here 希望我幫了你。

相關問題