共享指针交换方法标识更改
shared pointer swap method identity change
背景:我不知道是什么原因让我进行了这个实验,但我正在尝试测试一个内部使用智能指针的容器化链表。
以下是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,您需要简化它。只需按照对常规节点指针的操作即可。你的大问题是使用"交换"将你的实际数据置于一个临时对象的唯一控制之下,这将很快完成任务,即销毁你的所有数据。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 使用std::函数映射对象方法
- 调用具有未标识类型的类的方法
- 共享指针交换方法标识更改
- 有没有更好的方法来处理将标识分配给层次结构中的类以供运行时使用
- 方法,用于在代码中唯一标识方法调用,以测试调用序列是否未更改
- 标识继承类的最佳方法
- 初始化 C++11 数组的最佳方法,主要是标识映射
- 标识派生类类型的正确方法(类型实体VS dynamic_case)
- 无法调用派生类的方法 - 编译器将对象实例标识为基类