2014-02-14 132 views
0

我在想,如果我不得不刪除這個指針例子是這樣的:C++ /析構函數 - 運營商刪除

class Person 
{ 
    public: 
    Person(char *name) :_name(name) {} 

    // Is this delete necessary? 
    ~Person() { 
     cout<<"Godbay Person"<<endl; 
     delete _name; 
    } 

    private: 
    char * _name; 
} 
+3

不可能告訴,但很可能不會。 'Person'甚至不知道指針是指向一個動態分配的'char'或'char'數組。 – juanchopanza

+0

「人們甚至不知道...」name是Person類的字段,所以應該知道它指向動態分配的char。 – Radek

+0

@AllanBradley在你的代碼中,'name'是傳遞給構造函數的指針的副本,所以類不可能知道它是否被動態分配。(當然,在現代C++中,我無法想象會動態分配char或char的數組)。 –

回答

1

無論如何這肯定是錯誤的。

有兩種可能性:

  1. 這個名字是在自由存儲區中創建專屬於你的目標,你的對象必須承擔所有權。然後名稱必須被刪除。

  2. 該名稱不是在免費商店中創建的(例如,作爲一個字符串litaral,這很有可能),或者某個其他對象正在管理該名稱,因此您的對象不應該承擔所有權。然後任何刪除都會對您的程序造成嚴重破壞。

那麼,即使在第一種情況下,我爲什麼會說錯?因爲name聽起來像一個字符串,而不是單個字符,這意味着name*將指向一個動態分配的字符數組。在這種情況下,刪除它的正確方法是delete[] name

但是:如果可能的話,避免使用普通(char)的指針,爲1的情況下使用一些內存管理類代替(字符串類或smartpointers),擺脫手工管理內存所有權的頭痛。 deletedelete[]應該只在您的代碼中很少出現,除非您無法訪問最新的C++編譯器。

+0

有些情況下,普通的'char'指針是有效的;例如,指向字符串的字符串必須是字符串文字。有些情況下你沒有選擇;當你連接到在C. –

+0

@JamesKanze右邊定義的接口時,也有例外,我相應地編輯了我的答案。然而,在這兩種情況下,你提到'delete []'都是錯誤的,這個字符串應該不會被銷燬,或者它應該回到它所來自的接口。哪些可能/應該被包裝進合適的RAII類本身,例如一個帶定製刪除器的'shared/unique_ptr'。 –

+0

在任何寫得很好的代碼中,'delete []'都是錯誤的,因爲不應該做任何'new []'。 –

0

一般情況下,你必須調用刪除每次創建一個指向新的時間。

+0

這僅適用於C++ 11之前的版本。在C++ 11中,你*應該*使用智能指針,所以*幾乎*你寫的任何'new'都是爲一個對象賦予一個'unique_ptr',並且*幾乎*不刪除應該被寫入。 (例外是自己的內存管理類)。在C++ 14中'make_unique'使得最後的'new's也被淘汰。 –

+0

事實上,標籤是C++而不是C++ 11 ..(: –

+0

這是,但自從C++ 11已經成爲標準已有兩年多的時間以來,*一般*建議應該是最新的 –

0

這取決於創建過程。

在這種情況下,沒有:

Person *p = new Person("John"); 

在這種情況下是:

char *str = new char[32]; 
::strcpy(str, "John"); 
Person *p = new Person(str); 

在這種情況下,是的,但::free函數,而不是運營商delete

char *str = (char *)::malloc(32); 
::strcpy(str, "John"); 
Person *p = new Person(str); 

考慮使用std::string而不是C字符串指針。

1

這是一個誰擁有分配的內存的問題,在這種情況下它看起來像人沒有擁有它,所以沒有,所以沒有必要刪除。在Person中使用像你這樣的原始指針總會引發關於所有權的問題,這就是爲什麼建議使用shared_ptr/unique_ptr來代替或者甚至更好std::string,因爲它似乎是一個字符串。