【发布时间】:2021-10-10 05:42:11
【问题描述】:
首先我对两个列表都只使用 shared_ptr:
struct Elem {
string cargo;
shared_ptr<Elem> next;
Elem(string cargo) {
this->cargo = cargo;
}
~Elem() {
cout << "delete Elem " << cargo << endl;
}
};
static shared_ptr<Elem> make3nonCyclic() {
shared_ptr<Elem> A(new Elem("A"));
shared_ptr<Elem> B(new Elem("B"));
shared_ptr<Elem> C(new Elem("C"));
A->next = B;
B->next = C;
return A;
}
static shared_ptr<Elem> make3cyclic() {
shared_ptr<Elem> A(new Elem("A"));
shared_ptr<Elem> B(new Elem("B"));
shared_ptr<Elem> C(new Elem("C"));
A->next = B;
B->next = C;
C->next = A;
return A;
}
static void test2() {
//non cyclic list of three
shared_ptr<Elem> head = make3nonCyclic();
head = head->next;
cout << "elem A should be deleeted" << endl;
}
static void test3() {
//cyclic list of three
shared_ptr<Elem> head = make3cyclic();
head = head->next;
cout << "elem A should not be deleeted" << endl;
}
对于非循环列表工作正常,(除了调用递归而不是尾迭代) 对于循环,不释放。 我试过了
- 更改weak_ptr 旁边的字段:发布太早了
- 将make3cyclic 中的返回类型和test3 中的head 更改为weak_ptr:不释放。 这个样品怎么做?还有更复杂的:
struct Node {
shared_ptr<Node> parent;
Node(shared_ptr<Node> parent) {
this->parent = parent;
if (parent!=nullptr)
depth = parent->depth+1;
}
int depth = 0;
vector<shared_ptr<Node>> children;
shared_ptr<Node> addChild(shared_ptr<Node> parent) {
shared_ptr<Node> child(new Node(parent));
children.push_back(child);
return child;
}
};
在“weak_ptr 如何工作?”我可以看到: "当“使用计数”达到零时,指针被删除。
当“弱计数”达到零(这意味着“使用计数”也必须为零,见上文)时,“计数器”辅助对象被删除。”
我认为指针对象和计数器对象密切相关,如果释放计数器对象,指针对象就不能存在。
【问题讨论】:
-
关于列表的第一课是,如果将 lists 与 nodes 分开,处理起来会变得简单得多。
-
至于你的问题,你永远不会切断到
A节点的所有连接,你仍然有一个到它的链接(来自C节点)。如果你想从列表中删除一个节点,你需要更新 all 指向它的指针(C应该指向B)。 -
是的,但是如果 A、B、C 和 head 超出范围,则应该释放整个循环列表。从 C 到 A 的链接应该很弱?但字段 C.next 与 A.next 和 B.next 的类型相同。
-
whole cyclic list should be freed如果是循环,则不会释放任何内容,因为每个共享指针仍然有一个用户,即循环中的前一个元素。你必须打破循环。 -
通过设置 head.next = nullptr ?
标签: c++ smart-pointers