[英]C++ destructor example
我的C ++有點生銹,但是我制作了一個反向鏈接列表的程序,現在我正試圖為其編寫適當的析構函數,但是我不知道該破壞什么。 這是我的班級定義:
class LinkedList
{
private:ListElement *start;
public:LinkedList();
public:void AddElement(int val);
public:void PrintList();
public:void InvertList();
};
class ListElement
{
public:int value;
public:ListElement * link;
public:ListElement(int val);
public:ListElement();
};
class Stack
{
private:ListElement ** stack;
private:int index;
public:Stack(int size);
public:void push(ListElement * le);
public:ListElement * pop();
};
堆棧是當我反轉列表時使用的。 無論如何...我將如何為這些編寫析構函數? 我剛在想:
對於ListElement,將值設為0,並將鏈接設為0(NULL)。
對於LinkedList,請遍歷所有元素,然后為所有元素調用ListElementDestructor。
我對此不太確定,因為據我了解,析構函數會自動調用成員對象的析構函數,因此在這種情況下,僅為LinkedList編寫一個空的析構函數就足夠了嗎? 我不知道...這就是為什么我問
對於堆棧,我不知道...在反轉列表之后,指針已經為0(NULL),因為它們全部彈出。
我有點困惑。 有人可以幫忙嗎? 先感謝您。
您破壞了需要破壞的事物。 如果您的類使用new創建對象,則可能需要一個析構函數,該析構函數使用析構函數將其刪除。 請注意,像LinkedList這樣的容器應僅包含已動態分配的元素或未動態分配的元素。 如果您將兩者混合使用,或者將原件和副本混合使用(如我懷疑的那樣),則可能需要使用智能指針或引用計數。
其次,如果您真的需要反向一個單鏈表(在30年的編程工作中我從未做過),那么您只是在使用錯誤的數據結構-您應該使用雙鏈表,在這種情況下不需要做任何事情。
第三,我可以說您的C ++風格是非慣用的,對我而言幾乎是不可讀的-使C ++看起來像Java並不是一個好主意。 改成:
class LinkedList
{
private:
ListElement *start;
public:
LinkedList();
void AddElement(int val);
void PrintList();
void InvertList();
};
對於ListElement,將值設為0,並將鏈接設為0(NULL)。
您不需要重置析構函數中的任何值,因為在執行析構函數后這些值將不存在。
您需要確定的主要事情是,使用delete
(或在數組的情況下, delete []
)刪除堆上分配的所有元素(即Using new
)。
對於LinkedList,請遍歷所有元素,然后為所有元素調用ListElementDestructor。
對於在堆棧上分配的對象,當對象超出范圍時會自動調用它。
對於動態分配的對象(即使用new
創建的對象),在使用delete
析構函數時將調用該析構函數。 換句話說,您不需要調用任何析構函數,因為如果正確清理對象,它們將被自動調用。
假設(我假設)您要在LinkedList類的堆上分配新的ListElement,則應確保在LinkedList析構函數中,通過遍歷列表並在每個ListElement上調用delete(在您擁有當然從中檢索下一個列表元素的地址)。 像這樣:
ListElement* current = list.start;
while( current ){
ListElement* next = current->next;
delete current;
current = next;
}
ListElement類中沒有什么需要清除的,因為盡管它有一個指向下一個元素的指針,但刪除可能應該在LinkedList類中進行處理,這意味着它不需要析構函數。
不需要為每個類編寫析構函數,因為編譯器會自動為您生成一個空的析構函數。
正如我在評論中所說,您不應該使用堆棧來反轉鏈接列表。 您應該只是交換指針的方向。
一個大致的例子,您想要的東西。
ListElement* previous = 0;
ListElement* current = list.start;
while( current->next ){
//copy the address of current item on the list
ListElement* next = current->next;
//point the current list item to the previous list item
current->next = previous;
//set the current list item to the next list item
current = next;
//and the previous list item to the current one
previous = current;
}
//set the start of the list to what was the end
list.start = current;
LinkedList類創建ListElements。 因此,您需要從列表的開頭到結尾循環(除非它為空。)和:
delete currentElement;
在LinkedList析構函數中。 由於ListElement將值存儲為'int',因此您實際上不需要在這里釋放內存。 就像你想的那樣。
同樣,無需釋放Stack類的析構函數中的內存。 通常,刪除所有新內容! 並讓一個人(班)負責這項工作!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.