指针共享成语

时间:2015-12-01 14:56:48

标签: c++ pointers shared-ptr smart-pointers unique-ptr

在一般情况下,我无法想办法做到这一点。假设我有2个类,并且它们保持彼此的指针:

class first {
    unique_ptr<second> p2;
public:
    first() : p2(this) {}
};

class second {
    first* p1;
public:
    second(first* arg) : p1(arg) {}
};

这一切都很好用,但我真正想要的是使用shared_ptr作为second的一部分,因为second对象也可以独立于{{1}创建}。他们只会传递一个指向first构造的指针,但他们不知道它是否已经消失。

我无法first second::p1因为我不知道如何从shared_ptr传递this

有没有可以帮助我解决这个问题的习语?

2 个答案:

答案 0 :(得分:1)

有一点需要注意,你可以只在堆上创建实例。使用std::shared_from_this将是一个很好的解决方案但它只能在对象存在std::shared_ptr时调用,这在构造函数完成之前是不可能的,即使使用std::make_shared和{{{ 1}}抛出异常。

相反,我们确保创建此类实例的唯一方法是通过静态函数进行必要的设置。

std::bad_weak_ptr

修改:使用#include <cassert> #include <memory> class second; class first { struct Unconstructable {}; std::unique_ptr<second> p2; public: first(Unconstructable) : p2() {} static std::shared_ptr<first> create() { Unconstructable u; auto f = std::make_shared<first>(u); f->p2 = std::make_unique<second>(f); return f; } }; class second { std::shared_ptr<first> p1; public: second(std::shared_ptr<first> arg) : p1(arg) {} }; int main() { auto f = first::create(); } 并非真正必要,但使用Unconstructable时需要使用std::make_unique。如果我简单地将构造函数设为私有,那么std::make_unique将无法编译,即使我将其设为friend函数,因为实现使用内部帮助函数。将私有struct作为构造函数参数是一种绕过此方法的方法,同时仍然阻止构造在类本身之外发生。

答案 1 :(得分:0)

从我的评论中复制,因为OP表示这是他可以接受的答案。

不幸的是,没有安全的方法可以做到这一点 - 对于构造函数的简单问题而言,对于如何分配对象没有丝毫的了解。如果它根本没有动态分配怎么办?

如另一条评论中所示,

enable_shared_from_this也不是解决方案 - 它只允许从类中隐藏的shared_ptr中获取weak_ptr。但是,只要已经创建了至少一个shared_ptr并持有锁,这只是安全的 - 再次,这不是构造函数可以确保的。