2011-09-08 38 views
0

我一直無法找到這個問題的好答案。複製構造函數的C++幫助函數

我正在研究一個C++程序,我試圖實現一個名爲的副本,它將另一個對象作爲參數的引用。然後,它返回該對象的深層副本。

在我的項目的一些背景:場景類包含指針的動態數組(稱爲「圖像」)爲null或圖片類,這裏沒有顯示的實例 - 但工程因爲它應該(它繼承了它的所有方法從第三方庫,EasyBMP)

我這樣做的原因是避免重複在兩個地方的代碼,但它很可能是我採取了錯誤的方法。

我調用這個函數在我的賦值操作符:

Scene const & Scene::operator=(Scene const & source) 
{ 
    if (this != &source) { 
     clear(); 
     copy(source); 
    } 
    return *this; 
} 

我的拷貝構造函數:

Scene::Scene(Scene const & source) 
{ 
    copy(source); 
} 

最後,我copy()方法是這樣的:

Scene const & Scene::copy(Scene const & source) 
{ 
    Scene res(source.Max); 
    for (int i=0; i<res.Max; i++) 
    { 
     delete res.Images[i]; 
     if (source.Images[i] != NULL) 
      res.Images[i] = new Image(*(source.Images[i])); 
     else 
      res.Images[i] = NULL; 
    } 

    return res; 
} 

目前,它不起作用。我可以看到的一個問題是,我試圖在複製函數結束後立即返回一個超出範圍的變量。我之前嘗試過返回一個引用,但是編譯器拋出錯誤,並且這無助於範圍問題。

但我甚至不確定我的邏輯是否正確,即,你甚至可以在構造函數中做這樣的事情嗎?或者我應該明確寫出複製構造函數和賦值運算符中的代碼(不執行幫助方法複製)?

我很新C++和指針,所以任何指導將不勝感激。

+0

[用於C++新手入門C++書籍指南的義務鏈接](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。說真的,如果你剛剛對C++有所瞭解,那麼選擇一本好的C++書籍並閱讀它。 –

+0

實際上,我現在正在閱讀幾個 - 但感謝鏈接,我一定會看看那些(豐富的!)資源! – mwoz

+0

啊,這很好。如果您在學習期間遇到*特定問題,請毫不猶豫地詢問Stack Overflow。 –

回答

0
Scene const & Scene::operator=(Scene const & source); 

重載賦值運算符的副本到參數中的內容接收。對於copy,不需要返回任何東西或創建本地對象。只需從這個來源成員聰明的副本。

void Scene::copy(Scene const & source){ 
    // Member wise copy from this to source 
} 

Rule of three應該有助於更好地理解這些。

3

有一種更方便,更習慣的方式來做你想做的事:the copy-and-swap idiom

// N.B. Not tested, but shows the basic structure of the copy-and-swap idiom. 
class Scene 
{ 
public: 
    Scene(int) 
    { 
     // Initialize a pointer array of Images 
    } 

    ~Scene() 
    { 
     // Get rid of our pointer array of Images 
    } 

    // Copy constructor 
    // N.B. Not exception safe! 
    Scene(const Scene& rhs) : imgPtrArray(new Image*[rhs.max]) 
    { 
     // Perform deep copy of rhs 
     for (int i=0; i < rhs.max; ++i) 
     { 
      if (rhs.imgPtrArray[i] != 0)  
       imgPtrArray[i] = new Image(*(rhs.imgPtrArray[i])); 
      else 
       imgPtrArray[i] = 0; 
     }  
    } 

    // Copy assignment constructor 
    // When this is called, a temporary copy of Scene called rhs will be made. 
    // The above copy constructor will then be called. We then swap the 
    // members so that this Scene will have the copy and the temporary 
    // will destroy what we had. 
    Scene& operator=(Scene rhs) 
    { 
     swap(rhs); 
     return *this; 
    } 

    void swap(Scene& rhs) 
    { 
     // You can also use std::swap() on imgPtrArray 
     // and max. 
     Images** temp = imgPtrArray; 
     imgPtrArray = rhs.imgPtrArray; 
     rhs.imgPtrArray = temp; 
     int maxTemp = max; 
     max = rhs.max; 
     rhs.max = maxTemp; 
    } 

private: 
    Images** imgPtrArray; 
    int max; 
}; 

話雖這麼說,我強烈建議你pick up a good introductory C++ book,將涵蓋執行拷貝構造函數的基礎知識和正確拷貝賦值運算符。

+0

+1。我正要發佈這個。 – Nawaz

+0

+1 OP應該接受你的回答。 – Mahesh