在一般情况下,我无法想办法做到这一点。假设我有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
。
有没有可以帮助我解决这个问题的习语?
答案 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
并持有锁,这只是安全的 - 再次,这不是构造函数可以确保的。