C++ 链表:“->”运算符无法更改节点 object 的内部值
C++ Linked Lists: "->" operator fails to change the internal values of node object
我正在尝试用 C++ 编写双重 linked 列表,但我 运行 遇到了问题。当我在 linked 列表中追加一个数字时,它工作正常,但在构建 linked 列表数组后,追加函数不再起作用。每个 linked 列表的 header 都以某种方式丢失了它们的 link。这是我的代码(一直滚动到底部以找到我当前的 theories/diagnoses):
link编辑列表代码:
#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;
}
}
link编辑列表header代码:
#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 ->_
我目前的工作:
因此,如果您查看第一段代码,特别是我使用“--------”分隔的区域,我使用变量 "address" 引入了一点冗余,以便我可以看到发生了什么。似乎发生的情况是,当我通过附加函数将新节点插入 linked 列表时,"header.next" 字段不会更新。当我检查调试器时,变量 "address" 与 "header" 具有相同的内存位置,但是在地址上使用“->”运算符访问 header.next 并没有更新 header.next .我不明白这是为什么。如果我有header的内存位置并使用“->”,我想它应该给我header.next?有人可以指出我正确的方向吗?提前致谢。
该数组构造了一个新的 linkedList 实例,这就是您通过将其更改为指针数组来修复它的原因。
当 linkedList 被复制到数组的新实例中时,它执行了头节点和尾节点的浅表复制。节点 class 包含指针,因此必须实现复制构造函数以避免这种浅拷贝。
此代码中的直接错误已由 adding/deleting 这些复制构造函数修复。我没有做所有的副本,你真的必须这样做。
// 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 上的析构函数,因为你创建了新节点,但永远不会销毁它们。
附加说明:我将 header(node{-1}) 更改为 header{-1} 因为不再可能复制节点,因此不能使用临时对象复制到 header 中。但你并不需要它。
我正在尝试用 C++ 编写双重 linked 列表,但我 运行 遇到了问题。当我在 linked 列表中追加一个数字时,它工作正常,但在构建 linked 列表数组后,追加函数不再起作用。每个 linked 列表的 header 都以某种方式丢失了它们的 link。这是我的代码(一直滚动到底部以找到我当前的 theories/diagnoses):
link编辑列表代码:
#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;
}
}
link编辑列表header代码:
#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 ->_
我目前的工作: 因此,如果您查看第一段代码,特别是我使用“--------”分隔的区域,我使用变量 "address" 引入了一点冗余,以便我可以看到发生了什么。似乎发生的情况是,当我通过附加函数将新节点插入 linked 列表时,"header.next" 字段不会更新。当我检查调试器时,变量 "address" 与 "header" 具有相同的内存位置,但是在地址上使用“->”运算符访问 header.next 并没有更新 header.next .我不明白这是为什么。如果我有header的内存位置并使用“->”,我想它应该给我header.next?有人可以指出我正确的方向吗?提前致谢。
该数组构造了一个新的 linkedList 实例,这就是您通过将其更改为指针数组来修复它的原因。
当 linkedList 被复制到数组的新实例中时,它执行了头节点和尾节点的浅表复制。节点 class 包含指针,因此必须实现复制构造函数以避免这种浅拷贝。
此代码中的直接错误已由 adding/deleting 这些复制构造函数修复。我没有做所有的副本,你真的必须这样做。
// 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 上的析构函数,因为你创建了新节点,但永远不会销毁它们。
附加说明:我将 header(node{-1}) 更改为 header{-1} 因为不再可能复制节点,因此不能使用临时对象复制到 header 中。但你并不需要它。