C++ 链表:"->"运算符无法更改节点对象的内部值

C++ Linked Lists: "->" operator fails to change the internal values of node object

本文关键字:节点 对象 内部 运算符 链表 gt C++      更新时间:2023-10-16

我正在尝试编码C 中的双重链接列表,但我遇到了一个问题。当我在链接列表中附加一个数字时,它可以正常工作,但是在构造了链接列表的数组后,附录函数不再可行。以某种方式,每个链接列表的标题失去了链接。这是我的代码(一直滚动到底部以找到我的当前理论/诊断):

链接列表代码:

#include "linkedList.hpp"
#include <iostream>
#include <stdexcept>
linkedList::node::node(int value)
{
    internalValue = value;
    next = nullptr;
    previous = nullptr;
};
linkedList::linkedList()
: header{node(-2)}, trailer{node(-2)}
{
    trailer.previous = &header;
    header.next = &trailer;
    size = 0;
}
int linkedList::getLength()
{
    return size;
}
void linkedList::appendElement(int value)
{
    node * newNode = new node(value);
    newNode->next = &trailer;
    newNode->previous = trailer.previous;
    // ------------------------------------------------------
    node * address = trailer.previous;
    address->next = newNode;
    // ------------------------------------------------------
    trailer.previous = newNode;
    size = size + 1;
}

void linkedList::print()
{
    node * current = header.next;
    std::string listOfValues;
    while (current -> next != nullptr)
    {
        //std::cout << current -> internalValue << "->";
        listOfValues = listOfValues + "->" + std::to_string(current -> internalValue);
        current = current->next;
    }
    listOfValues = listOfValues + "->_ ";
    std::cout << listOfValues << "n";
}
int linkedList::getElementAt(int index)
{
    if (index < 0 || index >= size)
    {
        throw std::out_of_range ("Out of Range");
    }
    else
    {
        int count = index;
        node * current = &header;
        while (count > 0)
        {
            current = current -> next;
            count = count - 1;
        }
        return current -> next -> internalValue;
    }
}

链接列表标头代码:

#ifndef linkedList_hpp
#define linkedList_hpp
class linkedList
{
protected:
private:
    class node
    {
    public:
        node(int value);
        int internalValue;
        node * next;
        node * previous;
    };
    int size;
    node trailer;
    node header;
public:
    explicit linkedList();
    int getLength();
    void appendElement(int value);
    void print();
    int getElementAt(int index);

};
#endif /* linkedList_hpp */

将数字插入列表有效:

linkedList list1;
list1.appendElement(42);
list1.appendElement(99);
list1.print();
// prints ->42->99->_

插入数组中的列表不起作用:

linkedList list2;
linkedList list_array[1] = { list2 };
list_array[0].appendElement(42);
list_array[0].appendElement(99);
list_array[0].print();
// prints ->_

到目前为止我的工作:因此,如果您查看第一个代码,特别是我使用" --------"分离的区域,我引入了一些冗余,以变量"地址",以便可以看到发生了什么。似乎发生的事情是,当我通过附录函数将新节点插入链接列表时," header.next"字段不会更新。当我检查调试器时,变量"地址"具有与"标头"相同的内存位置,但是使用" ->"运算符在地址上的访问header.next上没有更新header.next。我不明白为什么那是。如果我有标头的内存位置并使用" ->",我认为它应该给我header.next?有人可以将我指向正确的方向吗?预先感谢。

阵列构造了linkedlist的新实例,这就是为什么您将其修复为将其更改为指针数组的原因。

将LinkedList复制到数组的新实例中时,它执行了标头和拖车节点的浅副本。节点类包含指针,因此必须实现复制构造函数以避免此浅副本。

通过添加/删除这些复制构造函数来修复此代码中的直接错误。我没有做所有的副本,您真的必须。

// we don't want to copy the pointers from one node to a new node
// otherwise things get double deleted and you crash, later,
// when you start implementing the destructors
// so just make it impossible to copy a node
class node {
private:
    node(const node &ref); // use delete syntax from c++11 if available
public:
    node(int value);
    ...
linkedList::linkedList(const linkedList &ref)
    : header{-1}, trailer{-2}
{
    trailer.previous = &header;
    header.next = &trailer;
    size = 0;
    // now append a copy of every data node from ref
}

此外,三个规则意味着您必须实施的更多内容,无论如何您确实需要在LinkedList上的击曲线,因为您创建了新的节点,但永远不会破坏它们。

附加说明:我将标头(节点{-1})更改为标头{-1},因为不再可以复制节点,因此不能将临时对象用于复制到标题中。但是您无论如何都不需要它。