我找不到一个完整的示例,说明如何消除shared_ptr
之间的强循环引用。
问题是如何使用weak_ptr
“关闭”通用元素链并使用weak_ptr
访问“next”元素。
谢谢。
修改
例如,假设Element e1, e2, e3;
的指针位于下一个元素的内部。
在C中我们做
e1->Next = e2;
e2->Next = e3;
e3->Next = e1;
......我们可以做e1->Next->Next->Next->Next->Next
等。
在使用shared_ptr
的C ++中,由于循环引用而无法执行最后->Next = e1
,因此析构函数不会释放所有Element
。
我们需要weak_ptr
:但是哪种策略可以获得相同的结果?
答案 0 :(得分:-1)
好的我找到了解决方案。
当我需要从最后访问链的第一个元素(object,struct或typedef_data)时,只需使用 weak_prt 使用lock()
(可能与expired()
检查poiter是否仍然存在...)
示例:
std::weak_ptr<int> gw;
void f()
{
if (auto spt = gw.lock()) { // Has to be copied into a shared_ptr before usage
std::cout << *spt << "\n";
}
else {
std::cout << "gw is expired\n";
}
}
int main() {
{ //into the scope
auto sp = std::make_shared<int>(42);
gw = sp;
f();
}
// out of the scope
f();
}
因此,输出将是:
42
gw is expired
此示例中未使用 expired()
,但应在lock()
之前使用,并且始终检查lock()
的返回值
答案 1 :(得分:-2)
这个讨论可能很有用:When is std::weak_ptr useful?。 特别是,第三个答案就是您要搜索的内容。
上面的示例是关于一个树,其中每个节点的子节点都有shared_ptr,而父节点有一个weak_ptr。如果您希望通过连接的节点列表创建一个循环缓冲区,那么您必须使用强引用创建一个普通列表,然后关闭循环,将weak_ptr从最后一个节点添加到第一个节点。当遍历列表时,你到达weak_ptr并且你想继续,你可以得到一个shared_ptr调用weak_ptr上的lock方法;请注意,lock不会破坏weak_ptr。
从weak_ptr获取shared_ptr的另一种方法是构造一个传递给构造函数weak_ptr的shared_ptr。在成功的情况下结果是相同的,而如果weak_ptr已过期则结果大不相同(锁定返回空的shared_ptr,而构造函数抛出异常)。