2014-04-21 20 views
0

我有一個名爲「node」的類。我將一堆節點對象鏈接在一起形成一個鏈表。當調用「節點」析構函數時,它只會刪除第一個節點。如何遍歷整個鏈接的節點列表並刪除每個節點對象?使用析構函數釋放鏈接對象

下面是類的定義:

class Node 
{ 
private: 
double coeff; 
int exponent; 
Node *next; 
public: 

Node(double c, int e, Node *nodeobjectPtr) 
{ 
    coeff = c; 
    exponent = e; 
    next = nodeobjectPtr; 
} 

~Node() 
{ 
    printf("Node Destroyed"); 
} 

析構函數調用刪除的指針鏈接節點列表的第一個節點調用。

+0

如果你只有幾個節點,只要做'刪除下一個' - 它會遞歸地破壞節點。如果你有幾百或幾千個,那麼創建一個LinkedList對象,並在那裏迭代地刪除它們,因爲否則就會發生堆棧溢出。 –

+0

「如果你只有幾個節點」 - 你怎麼看?如果太多,你剛剛吹了堆棧。無界遞歸在C++中總是一個壞主意。 –

+0

讓鏈表刪除它需要刪除的節點,而不要給節點類負責。 '刪除下一個'建議只會將OP畫在一個角落。如果以後會怎樣,所有需要刪除的都是列表中的單個節點? '刪除下一個'將是災難性的。 – PaulMcKenzie

回答

1

如何迭代節點的整個鏈表並刪除每個節點對象?

這將是cleaner如果你有一個單獨的類來管理整個列表,以便節點可以是簡單的數據結構。然後你只需要在列表中的析構函數的簡單循環:

while (head) { 
    Node * victim = head; 
    head = victim->next; // Careful: read this before deleting 
    delete victim; 
} 

如果你真的想列表管理委託給節點本身,你需要有點小心:

while (next) { 
    Node * victim = next; 
    next = victim->next; 
    victim->next = nullptr; // Careful: avoid recursion 
    delete victim; 
} 

在這個方案下,在從列表中刪除節點時,您還需要小心 - 再次確保您重置其指針,以便它不會刪除列表的其餘部分。這是另一個支持單獨「列表」類的理由。

1

由於您不知道列表中有多少個節點,因此如果您沒有確定的界限,那麼遞歸調用析構函數並不是一個好主意,因爲每個調用都使用一些堆棧空間,並且在可用堆棧空間耗盡,你會得到未定義的行爲,就像崩潰。因此,如果您絕對想要在節點的析構函數中解除分配以下節點,那麼它必須在銷燬它之前首先取消每個節點之間的鏈接。

它可以是這樣的:

Node* unlink(Node*& p) 
{ 
    Node* result = p; 
    p = p->next; 
    result->next = nullptr; 
    return result; 
} 

Node::~Node() 
{ 
    while(next != nullptr) 
    { 
     delete unlink(next); 
    } 
} 

不過還好,讓已在鏈表節點的所有權List對象。

當然,除非這是出於學習目的或有一個很好的理由推出自己的鏈表,只使用一個std::vector(是的,我的意思是說,不std::list)。