C++ 链表的构造函数

C++ 链表的构造函数,c++,linked-list,doubly-linked-list,C++,Linked List,Doubly Linked List,我正在尝试实现一个链表 列表有私有变量*head、*tail、count 我了解数据结构中的逻辑,但我承认我是C++新手,所以我觉得我可能不正确地使用构造函数。p> *head和*tail是列表节点指针。然后,列表节点具有指向上一个和下一个(双链接列表)的指针 以下是我尝试过的: List::List():head(), tail(), count(0) { head->previous = NULL; head->next = tail; tail->

我正在尝试实现一个链表

列表有私有变量*head、*tail、count

<>我了解数据结构中的逻辑,但我承认我是C++新手,所以我觉得我可能不正确地使用构造函数。p> *head和*tail是列表节点指针。然后,列表节点具有指向上一个和下一个(双链接列表)的指针

以下是我尝试过的:

List::List():head(), tail(), count(0) {
    head->previous = NULL; 
    head->next = tail;
    tail->previous = head; 
    tail->next = NULL; 
}

我的程序可以编译,但当它试图使用此构造函数创建新列表时崩溃。有什么建议吗

通常,
head
tail
将是空列表的空指针,因此如下所示取消对它们的引用:

head->previous = NULL;
将是未定义的行为

构造函数将是:

List::List() : head(0), tail(0), count(0) {}
<>(或使用<代码> NulLPTR < /代码> <代码>头<代码>和<代码>尾<代码>如果您的C++足够先进) 如果您的用户类型喜欢列表开头和结尾的虚拟节点,则在尝试使用它们之前,您需要分配它们:

List::List() : count(0) {
    head = new somethingOrOther();
    tail = new somethingOrOther();

    head->previous = NULL; 
    head->next = tail;

    tail->previous = head; 
    tail->next = NULL; 
}
这种技巧通常用于大大简化列表的插入和删除,因为您不必担心是在末尾插入还是在开头删除


缺点是列表遍历和节点搜索(包括删除)必须从
head->next
开始,以
tail->previous
结束,但这通常比担心以前的问题更简单。

啊,就是这样!非常感谢。我还不能很好地理解指针和内存分配,所以我甚至不确定它到底做了什么。基本上,我只是想做一个列表,上面有一些我可以操作的头尾指针。我知道count(0)将列表的count设置为0,那么为什么head()不起作用,我们必须执行head=newlistnode()?我想做的和你刚才做的有什么区别?这里完全是新手!因为
head()
head=newlistnode()
做两件完全不同的事情。第一个默认值初始化一个指针,第二个默认值构造一个新的ListNode并为该ListNode分配一个指针。您应该避免认为“我理解我在做什么,因此编译器也应该这样做”。编译器将完全按照您所说的做,不多不少。因此,你必须准确地理解你所使用的所有语言结构的真正用途。@Tidus,约翰说得最好
:head()
为您提供一个空指针,如
:head(0)
。显式调用
new
并将其分配给
head
将在该指针后面放置一个真实对象,这样就不会取消引用。