[英]When should I use destruction function of my own in C++?
最近,我正在使用C ++研究OOP,在以下情況下應該使用自己的破壞函數時,我感到很困惑:
class T1{
private:
int data;
public:
T1(){...};
~T1(){}; // should I write my own function here?
};
class T2{
private:
T1* pointer_to_T1;
public:
T2(){...};
~T2(){}; // should I write my own function here?
};
class Node{
public:
int data;
Node* next;
};
class T3{
private:
int size;
Node* head;
public:
T3(size){
head = new Node[size];
}
~T3(){}; // should I write my own function here?
};
上面的程序中有三個注釋可用來澄清我的問題。 我希望您能向他們解釋,如果能給我一個一般性的規則,我將不勝感激。
對於class T3
您正在分配新的內存,因此您將必須刪除處於分解狀態的已分配內存段。
class T3{
private:
int size;
Node* head;
public:
T3(size){
head = new Node[size];
}
~T3(){
delete[] head;
};
};
類的析構函數應執行刪除對象時所需的所有操作。
例如,它需要釋放該類動態分配的所有內存。
當您的類是基類,並且希望進行多態銷毀,並且希望銷毀對象時運行某些邏輯時,應該編寫一個析構函數。
如果對象擁有並管理資源 ,則可能需要一個構造函數。 不要忘記復制和賦值運算符。
該對象應自行清除。
IE,如果曾經在對象中分配內存(可能是在構造函數中完成),則應該在析構函數中分配該內存。
析構函數用於清理對象之后。 因此,您也可以做任何事情來幫助您做到這一點。
T1類不需要顯式定義析構函數。 由編譯器隱式定義析構函數就足夠了。
T2類需要顯式定義析構函數,以解除其具有類型指針的數據成員的分配。 否則會發生內存泄漏。
類節點不需要顯式定義析構函數。 T3類必須刪除Node類的所有指針,因為它控制着節點的分配和釋放。
您需要聲明一個析構函數:
在第一種情況下,您還需要提供或刪除副本構造函數和副本分配運算符; 否則,您最終可能會遇到兩個或多個嘗試管理同一資源的對象。 這被稱為“三個規則” 。 通常,您可以使用容器和智能指針等現成的類為您管理內存。 因此通常不需要自己去破壞者。 有人將此稱為“零規則”。
在第二種情況下,析構函數無需執行任何操作(假設該類沒有嘗試管理任何資源),它只需要是虛擬的即可。
對於您的特定示例:
T1
不需要析構函數 T2
可能取決於它是否應該管理指針所指向的內容。 如果是這樣,則考慮使用智能指針(如std::unique_ptr<T1>
替換指針。 T3
可能會這樣做,因為它似乎正在管理動態陣列。 您還需要考慮“三法則”。 或考慮使用std::vector<Node>
自動管理陣列。 我將嘗試以一種不特定於您的代碼段的一般方式進行回答。
通常會出現兩種一般情況,其中您將需要一個非平凡的析構函數。 這不是一個完整的列表; 只是最常見的情況。
1) 在(多態)層次結構中。 如果您的類是要從中派生的基類,則您的基類很有可能應該具有非平凡的析構函數。 而且,該析構函數可能應該是virtual
。 這樣就可以通過基類指針刪除派生類對象,如下所示:
class Foo
{
public:
virtual ~Foo(){}
};
class Bar : public Foo
{
};
int main()
{
Foo* obj = new Bar;
delete obj;
}
如果沒有virtual
析構函數,此程序將顯示“未定義行為”。
2) 當您的班級中的成員需要的不僅僅是瑣碎的破壞。 一個簡單的示例是,如果您的類的成員是使用new
創建的原始指針(不是智能指針)。 該指針將需要delete
d,而析構函數可能是正確的選擇。 如果您的類具有復制構造函數或復制賦值運算符( operator=
),則可以很好地表明您的類管理不可分解的成員。 如果您的類中有一個,則可能需要它們和一個析構函數來處理分配的所有內容。 (請參閱“三法則” ),但這並不是唯一的指示-您可能只有默認的構造函數,但仍然需要析構函數。 這取決於您的班級。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.