2009-12-10 552 views
9

它是好(和法律),刪除已被作爲一個函數參數傳遞,如該指針:使用刪除作爲函數的參數傳遞指針

#include<iostream> 

class test_class{ 
public: 
    test_class():h(9){} 
    int h; 
    ~test_class(){std::cout<<"deleted";} 
}; 

void delete_test(test_class* pointer_2){ 
    delete pointer_2; 
} 

int main(){ 
    test_class* pointer_1; 

    while(true){ 
     pointer_1 = new test_class; 

     //std::cout<<pointer_1->h; 

     delete_test(pointer_1); 
    } 
} 

現在這編譯好,但我只是想以確保它永遠是那樣的。

回答

11

它將始終編譯沒有錯誤。

將指針傳遞給函數並在函數中刪除它是一件好事,這可能是另一回事,具體取決於程序的具體情況。

您需要考慮的主要思想是指向數據的「所有權」。當你傳遞該指針時,調用函數是否擁有傳入的數據的所有權?即它是唯一能夠引用這些數據的地方嗎?您是否放棄了指向數據的所有權,調用函數不會再次引用數據?如果是這樣,那麼你必須刪除它。

如果調用函數可能再次引用數據,那麼您不得刪除它。

如果通過各種數據結構還有其他對數據的引用,那麼刪除這些數據是不安全的,除非你在代碼中有一些規則來確保你永遠不會再從這些地方引用數據。這很難做到,並且是許多編程錯誤的來源。

C++ tr1的shared_ptr < >是一個智能指針,可以幫助處理這種情況 - 它通過保持跟蹤數據引用數量的引用計數來管理此所有權概念。如果引用計數爲1,則有1個明確的所有者。如果引用計數大於1,則共享所有權。如果引用計數爲0,則不再有對該數據的引用,並且shared_ptr < >將在調用shared_ptr >析構函數時將其刪除。

+0

我總是發現令人驚訝的是,即使它是'const',刪除指針也是合法的。 – 2009-12-10 16:51:16

2

是的,這是完全合法的。只要它指向堆上分配的某個對象(或等於0),您就可以從delete指向任何地方的指針。

調用者是否期望他們的對象被函數刪除,這是另一個問題。

7

是的,這是有效的。

這通常在C中完成(顯然,使用malloc和free而不是new和delete)。在C++中,如果可以的話,通常最好使用其他內存管理習慣用法,如RAII

6

是的,它在C++中是合法的,但這樣做通常不被認爲是一種好的做法。執行newdelete的班級總是更好。

+0

我沒有在給定的代碼中的任何地方看到「執行新的」類。你可能意思是「阻止」而不是「階級」,但這並不總是可能的或有用的。 – 2009-12-10 15:28:17

+0

但是,該類可以使用將指針作爲參數的函數進行刪除。 – 2009-12-10 15:30:23

0

這樣做是完全合法的。您必須確保指針在該點之後不在調用方中使用。通常,執行刪除的函數的名稱應該表明正在發生的事情(例如,包含刪除,釋放,免費等)。另一個潛在的問題是確保指出的數據分配了新的而不是新的[]。

1

這是完全合法的,但在這種情況下,最好使用類似boost::shared_ptr的內容管理內存所有權。

0

這是有效的,並且在爲對象編寫清理方法時非常有用,儘管9/10次您希望將清理邏輯放入析構函數中。

儘管編寫單獨清理的一個很好的理由是,如果你想保持對象「活着」但暫時不用,也許在你偶爾需要一個新對象時拉出的數組或對象池中而不需要構造函數的開銷。

如果您要讓指針通過,您應該檢查以確保它們不爲空以避免任何未定義的行爲。

相關問題