2012-06-05 58 views
0

今天我很無聊,我想創建自己的小班級。我真的很喜歡.Net中的'System.String'類,它是Split/Replace/Remove等功能,我想試圖實現它們。自定義字符串類和析構函數?

然而,我的問題是析構函數。如果我有我的字符串類的多個實例保存相同的字符串,所有他們會嘗試和刪除[]當調用析構函數相同的內存?

例如:

void DoSomething() { 
    MyStringClass text = "Hello!"; 
    { 
     MyStringClass text2 = text; 
     // Do something with text2 
    } // text2 is destroyed, but so is the char* string in memory 
    // text now points to useless memory?? 
} 

上午我理解這一點吧?大聲笑。

感謝,

亞歷

編輯:

哎呀,我忘了,包括代碼:

class string { 
    unsigned int length; 
    char* text; 

public: 

    string() : length(0), text(NULL) { } 

    string(const char* str) { 
     if (!str) throw; 
     length = strlen(str); 
     text = new char[length]; 
     memcpy(text, str, length); 
    } 

    ~string() { 
     delete[] text; 
    } 
}; 
+7

這是不可能的,因爲你沒有向我們展示任何相關的代碼。但你應該閱讀[三規則](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-ree)。 –

+0

如果你有多個由同一個const char *構造的字符串,那麼當然它們不共享相同的存儲空間,因爲你明確地將存儲空間和memcpy加入到它中。但是,如果您複製或分配一個字符串,它將獲得相同的存儲空間,並且兩者都將嘗試刪除相同的存儲空間,因爲......請閱讀三條規則,如上所述。 – abarnert

+1

PS,通常遵循三法則的方法是定義所有三個。但是在這種情況下,您可能想要考慮一些不同的東西:一個不可複製的字符串持有者類,它有一個析構函數,然後您可以擁有不同的字符串類的字符串類(只需將字符串持有者作爲成員進行深度複製,只需擁有shared_ptr 等),而不必定義這三者中的任何一個。 – abarnert

回答

1

你是正確的 - 都將試圖delete []相同的內存塊。

您沒有爲您的類定義複製構造函數,因此您將得到默認的構造函數,它會執行指針的淺表副本。

text2超出範圍時,指針將爲delete [] d。當text1超出範圍時,同樣的指針將再次變爲delete []d,導致未定義的行爲。

有很多方法可以解決這個問題,最簡單的就是定義你的拷貝構造函數和賦值操作符。