使用smart_ptr和weak_ptr的循环缓冲区?

时间:2016-08-29 16:47:07

标签: c++ c++11

我找不到一个完整的示例,说明如何消除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:但是哪种策略可以获得相同的结果?

2 个答案:

答案 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,而构造函数抛出异常)。