共享指针交换方法标识更改

shared pointer swap method identity change

本文关键字:标识 方法 指针 交换 共享      更新时间:2023-10-16

背景:我不知道是什么原因让我进行了这个实验,但我正在尝试测试一个内部使用智能指针的容器化链表。

以下是repl链接:https://repl.it/@BasavarajNagar/GoodnaturedGlisteningSection-1

#include <memory>
using namespace std;
template<typename T>
class linkedlist {
private:
class node {
public:
T data;
shared_ptr<node> next;
node(T data) {
this->data = data;
}
};
// non const unique ptr
shared_ptr<node> head;
public:
void add(T data) {
cout<< "adding " << endl;// + data << endl;
if (head == nullptr) {
head = shared_ptr<node>(new node(data));
return;
}
shared_ptr<node> cursor;
cursor.swap(head);
// this works well
while (cursor != nullptr) {
cout << cursor->data << endl;
cursor = cursor->next;
}
cout << data << endl;
// this is the problematic assignment
cursor = shared_ptr<node>(new node(data));
}
void trace() {
shared_ptr<node> cursor;
cursor.swap(head);
cout << "trace" << endl;
while (cursor != nullptr) {
cout << cursor->data << endl;
cursor = cursor->next;
}
}
};
int main() {
std::cout << "Hello World!n";
linkedlist<int> ll;
ll.add(22);
ll.add(45);
ll.add(63);
ll.trace();
}

trace方法总是指向最后一个元素,在add方法中交换后头丢失。

注:我知道这不是生产质量的代码,而是为了理解智能指针的内部/怪癖。因此,请避免代码质量评论。

您严重误解了共享指针。https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr

您最需要的跟踪信息是node::node和node::~node。跟踪实际节点何时创建和销毁将对您有所帮助。您还必须了解范围。

快速批评你的"添加"功能(修复留给你,超出了问题的范围,对我发布太多有害):

它正确地创建了单个项目列表。但是,如果再次尝试添加,则将head移动到临时对象,将head设置为nullptr。然后在列表中循环光标,破坏任何可能存在的节点,直到不再存在为止。事实上,您刚刚将nullptr分配给cursor并不是一个问题,因为当您创建一个带有单个项目的新列表时,您会立即抛出它可能具有的任何值,该列表由cursor而不是head持有。然后超出范围,破坏光标,因此也破坏了刚刚添加到光标的新项目。

但最大的问题是你的跟踪函数,你用它来理解你的列表,但它并没有像你想要的那样做任何事情。这是最大的问题,因为你认为你根据坏信息了解发生了什么。如果trace对你撒谎,那么你就无法使用它来理解add。

这里有一个跟踪功能,它将正确打印列表的当前内容,而不会破坏它:

void trace() {
cout << "trace: ";
shared_ptr<node> cursor = head; // SHARE, do not lose head, read the docs
while (cursor.get()) {
cout << cursor->data << ", ";
cursor = cursor->next;
}
cout << endl;
}

我建议连续调用跟踪函数两次。如果它在打印列表时没有销毁列表,那么第二个调用应该具有与第一个相同的输出。要修复add,您需要简化它。只需按照对常规节点指针的操作即可。你的大问题是使用"交换"将你的实际数据置于一个临时对象的唯一控制之下,这将很快完成任务,即销毁你的所有数据。