2013-05-09 78 views
2

所以我想實現在C廠鏈表的運行++爲什麼解引用節點會破壞我的鏈表?

template<class T> 
class Node 
{ 
private: 
    Node *next; 
    T item; 

public: 
    Node(T item) 
     : item(item) 
    { 
     this->next = NULL; 
    } 

    Node<T> add(T item) { 
     this->next = new Node(item); 
     return *this->next; 
    } 

    bool hasNext() 
    { 
     return this->next == NULL; 
    } 

    Node<T> getNext() 
    { 
     return *this->next; 
    } 

    T value() 
    { 
     return this->item; 
    } 
}; 

void main() 
{ 
    Node<int> node(3); 
    node.add(3).add(4); 

    cout << node.value(); 
    cout << node.getNext().value(); 
    cout << node.getNext().getNext().value(); 

    cin.get(); 
} 

,但我無法得到它的工作。尤其是本節:

node.add(3).add(4); 

    cout << node.value(); 
    cout << node.getNext().value(); 
    cout << node.getNext().getNext().value(); 

如果我改變addgetNext函數返回Node<T>*,而不是Node<T>,它工作正常。但爲什麼解引用會導致代碼崩潰?我認爲.表示法比->更有意義,但我無法使其工作。我究竟做錯了什麼?

+2

被製成如果你有'add'返回一個節點'',則返回一個_copy_您正在然後修改。這意味着你會掉到列表的尾部:-)你正在尋找一個參考 - 在這兩個函數上返回'Node &'。 – 2013-05-09 15:53:59

+0

垃圾工程,真棒。那麼C++中的函數總是按值傳遞呢? (事先道歉我的c#/ java背景) – sircodesalot 2013-05-09 15:56:19

+1

是的。參考文獻通過,以及參考。它們的一個常用用途恰恰就是你的用例,它們通常也被用作'const T&',這樣你就可以通過引用,但確保沒有任何修改值。 – 2013-05-09 15:58:14

回答

7

現在您正在製作您添加的節點的副本,而不是返回您創建的實際節點。括號只是爲稍後需要查看代碼的其他人澄清一點。 ADD功能需要這樣的改變:

Node<T>& add(T item) { 
    this->next = new Node(item); 
    return *(this->next); 
} 

,或者你可以返回一個指向新創建的節點,但是這打破使用.,而不是->主。

還需要類似的變化,以next()

+0

嗯,我的C#背景阻礙了我的發現。所以C++總是做一個副本(假設你不返回一個指針或引用),無論類是什麼類型。那是對的嗎? – sircodesalot 2013-05-09 15:58:15

+1

是的,但只有淺拷貝(至少在指針方面)。假設你有一個指向包含在'Node'中的另一個對象的指針,它不會創建指向該對象的副本,但它將創建一個節點的副本和一個指向'Node'的副本。 – Danny 2013-05-09 16:00:08

相關問題