2016-07-25 21 views
0

新手C++程序員在這裏。比方說,我有一個嵌套類Inner的Outer類。 Inner包含一個指針成員,在構造期間設置爲Outer。外部包含一個函數AddNewInner(),它創建一個指向自身的新Inner,並將其添加到向量中。如何將包含指針成員的嵌套類的類實例複製到外部類?

class Outer { 

public: 

    class Inner { 
    public: 
     Inner(Outer* outerParent) : mOuterParent(outerParent) {} 
     Outer* mOuterParent; 
    } 

    void AddNewInner() { 
     Inner newInner(this); 
     mInnersVec.push_back(newInner); 
    } 

    vector<Inner> mInnersVec; 
} 

在創建Outer的新實例並調用AddNewInner()以將Inners添加到向量時,此工作正常。然而,當我嘗試創建外部實例的副本時,我遇到了一個問題:內部副本的Inners矢量不指向副本(它本身),它們仍指向原始外部。

Outer outerA; 
outerA.AddNewInner(); 
Outer* ptrA = outerA.mInnersVec[0].mOuterParent; // this points to outerA, good! 

Outer outerB = outerA; 
Outer* ptrB = outerB.mInnersVec[0].mOuterParent; // this still points to outerA, bad! 

我需要內部件的載體的拷貝來拷貝,而不是原來的。完成此事的最佳方式是什麼,或者可能有另一種方法來做同樣的事情?

+0

啊....你需要閱讀複製構造函數。 Google複製構造函數,深度複製,淺拷貝。那裏有很多參考資料。 – cplusplusrat

回答

0

正確,這是預期的行爲。當您使用C++創建對象的副本時,編譯器使用複製構造函數。如果您沒有爲類編寫自己的拷貝構造函數,那麼它使用編譯器生成的拷貝構造函數,它只是依次運行每個成員的(可能生成的)拷貝構造函數。

所以複製的Outer時,事件的順序是這樣的:

  • 編譯器運行(產生)拷貝構造函數用於Outer
  • 這會運行std::vector拷貝構造函數。此構造函數爲新矢量分配存儲,然後爲每個元素輪流運行復制構造函數
  • 因此Inner的(生成的)複製構造函數針對每個元素運行,該元素僅複製成員指針(仍指向原始Outer)。

爲了複製一個Outer何時更新Inner元素,你需要編寫Outer一個自定義的拷貝構造函數用於更新指針,只要你願意。事情是這樣:

Outer::Outer(const Outer& other) 
    : mInnersVec(other.mInnersVec) // Do initial vector copy 
{ 
    // Update vector elements 
    for (auto& elem : mInnersVec) { 
     elem.mOuterParent = this; 
    } 
} 

請注意,只要你寫了一個自定義的拷貝構造函數,你幾乎總是需要編寫一個自定義的賦值運算符太。我建議您閱讀您最喜愛的C++教科書中的複製和分配:-)。

0

您需要爲您的班級使用自定義copy constructor/assignment operator。這將允許您製作Outer* mOuterParent變量的深層副本;可能會創造一個新的。

當您複製指針時,您正在複製指向內存中特定地址空間的變量。複製指針只能讓你通過兩個'訪問器變量'來訪問同一個'真實變量'。

在你的榜樣特定outer對象將總是點到outer類的同一個實例指向該指針不管是特定對象的多少副本你做的Outer* mOuterParent變量。