2010-01-31 117 views
0

我的C++有點生疏,但我製作了一個反轉鏈接列表的程序,現在我正在嘗試爲它編寫適當的析構函數,但我不知道要摧毀什麼。這裏是我的班級定義: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),因爲它們全部都是poped。

我有點困惑。 任何人都可以幫忙嗎? 預先感謝您。

+4

只是交換元素之間的指針方向而不是使用堆棧更容易嗎? – Yacoby 2010-01-31 11:52:56

+4

重複私人和公共關鍵字是不必要的。只是做 私人: //私有變種聲明 公共: //公共var聲明 – batbrat 2010-01-31 11:56:22

+1

我還建議使listElement的「鏈接」成員專用,並提供一個只讀的訪問權限到下一個)方法 – davka 2010-01-31 12:32:24

回答

1

對於ListElement使值0,而鏈接0(NULL)。

您不需要重置析構函數中的任何值,因爲執行析構函數後值不會存在。

您需要確定的主要事情是使用delete(或在數組情況下爲delete [])刪除在堆上分配的所有元素(即使用new)。

對於LinkedList,檢查元素並調用它們中的所有ListElementDestructor。

對於在堆棧中分配的對象,當對象超出作用域時會自動調用該對象。
對於動態分配的對象(即使用new創建),當使用delete刪除 時,調用析構函數。換句話說,如果您正確清理對象,則不需要調用任何析構函數,因爲它們會自動調用。

假設你在LinkedList類的堆中分配新的ListElement,你應該確保在LinkedList析構函數中,每個ListElement在析構函數中被刪除,方法是在列表中向下走,並在每個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; 
+0

這是我學會在高中時學習的一種方式。如果你能告訴我如何扭轉指針,我會非常感激。我不知道這可以通過其他方式完成。這只是我頭上的第一件事。我接受任何其他解決方案。其實我會很感激。 – Para 2010-01-31 20:35:51

+0

@Para我編輯了我的帖子一些粗糙的(和未經測試的)通過交換指針來顛倒鏈接列表的代碼。即使它不能100%正確工作,它也應該讓你知道如何去做。 – Yacoby 2010-01-31 22:33:52

9

你摧毀了需要摧毀的東西。如果您的類使用new創建對象,那麼您可能需要使用析構函數將析構函數刪除。請注意像LinkedList這樣的容器應該只包含動態分配的元素或不包含的元素。如果您混淆了這兩者,或混合原件和副本,因爲我懷疑您正在做這些事情,您可能需要使用智能指針或引用計數。其次,如果你確實需要反轉一個單鏈表(30年編程中的某些事情,我從來不需要這樣做),那麼你只是簡單地使用了錯誤的數據結構 - 你應該使用一個雙向鏈表在這種情況下,不需要做任何事情。

第三,我可以說,你的C++風格是非慣用的,對我來說幾乎是不可讀的 - 使C++看起來像Java不是一個好主意。更改爲:

class LinkedList 
{ 
    private: 
     ListElement *start; 
    public: 
     LinkedList(); 
     void AddElement(int val); 
     void PrintList(); 
     void InvertList(); 
}; 
+0

嗯......我實際上曾將此作爲求職面試的一個問題:「編寫適當的代碼(包括類結構)以反轉單個鏈表」。我強調「單鏈表」。我也在帕斯卡高中和爪哇大學學習過。對不起,讓C++看起來像Java我真的不是故意的我想我已經習慣了這樣寫東西。 – Para 2010-01-31 20:32:55

1

LinkedList類創建ListElements。所以你需要循環從列表的開始到結尾(除非它是空的)。並且:

delete currentElement; 

在LinkedList析構函數中。由於ListElement將值存儲爲'int',因此您並不需要在此處釋放內存。就像你想的那樣。

同樣,不需要釋放Stack類的析構函數中的內存。一般來說,刪除你新的東西!並讓一個人(班級)負責這項工作!