2013-05-09 79 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

相关问题