2013-03-05 69 views
4

在設計動態分配內存的類時,遇到了有關內存分配的以下問題。我希望你們中的一些人能夠以正確的方向指出我應該如何更好地設計我的班級。我的類動態分配內存,因此也在其析構函數中刪除它。本地變量在超出範圍時刪除另一個變量的內存

爲了說明問題,請考慮以下傻類聲明:

class testClass{ 
    int* data; 
public: 
    testClass(){ 
     data = new int; 
     *data = 5; 
    } 
    ~testClass(){ 
     delete data; 
    } 
}; 

到目前爲止好。現在假設我主要創建這些對象中的一個

int main(){ 
    testClass myObject; 
    return 0; 
} 

當然還沒有問題。但是,假設我現在編寫一個函數,它將一個testClass對象作爲輸入並從main中調用它。

void doNoting(testClass copyOfMyObject){ 
    //do nothing 
} 
int main(){ 
    testClass myObject; 
    doNothing(myObject); 
    return 0; 
} 

這次,該函數創建一個局部變量copyOfMyObject,它只是myObject的一個副本。然後當該函數結束時,該本地對象自動具有調用它的析構函數,該函數將刪除其數據指針所指向的內存。但是,由於這與myObject的數據指針指向的內存相同,因此myObject在進程中無意中刪除了其內存。我的問題是:什麼是設計我的課程的更好方法?

+7

http:// stackoverflow。com/questions/4172722/what-the-the-rule-of-3 – 2013-03-05 18:38:27

回答

6

當您撥打doNothing()時,它會複製您的testClass對象,因爲它正在按值傳遞。不幸的是,當這個副本被銷燬時,它會調用析構函數,這會刪除原始實例testClass所使用的data

您想了解「複製構造函數」和「通過引用傳遞」。也就是說,你應該爲你的類定義一個拷貝構造函數,這樣當拷貝一個實例時,它爲它的data成員分配它自己的內存。另外,不要傳遞值,你可以傳遞一個指針或者對doNothing()的引用,以便不做任何拷貝。

+0

這非常合理!我無法相信我沒有意識到這是怎麼回事......我會確保實現一個複製構造函數。感謝您的快速反饋! – pontus 2013-03-05 18:51:58

2

您應該創建一個拷貝構造函數,那就是形式的構造:

testClass::testClass(const testClass &o) 
{ 
    // appropriate initialization here 
} 

在你的情況,「相應的初始化」可能意味着分配一個新的內存塊,並複製存儲從舊塊到新塊。或者它可能意味着做參考計數。管他呢。

您還應該在StackOverflow上閱讀關於Rule of Three的更多信息!

+0

+1;參考計數是我最初的想法 – 2013-03-05 18:54:11

0

下面是一個authority指導:與任何類{析構函數,賦值運算符,拷貝構造函數}一般需要所有3

你需要一個拷貝構造函數,這將使新的分配INT爲您的數據那會破壞那個,但不會影響原來的。

或者,您可以創建一個空白的私有拷貝構造函數,它可以有效地禁用它,強制用戶通過引用傳遞或另一種非拷貝的方式來執行操作。