3

考虑以下情况:

typedef boost::shared_ptr<B> BPtr;

class A
{
public:
    A() { b_ptr = BPtr(new B); }
    void a_func() { C::c_func(b_ptr); }
private:
    BPtr b_ptr;
}

class B
{
public:
    B() { b_ptr = BPtr(this); }
    void b_func() { C::c_func(b_ptr); }
private:
    BPtr b_ptr;
}

class C
{
public:
    static void c_func(BPtr b_ptr) { /*...*/ }
}

可以用 实例化 shared_ptrthis吗?
可以让两个 shared_ptr 对象指向同一个对象吗?(例如 A::b_ptr 和 B::b_ptr)
如果这两个之一超出范围 - B 的实例会被删除吗?

我猜我在做一些根本错误的事情。
我还考虑过使用 b_ptr 的依赖注入到 B 的构造函数,但这似乎也很错误。

更新:
澄清 - A 和 B 都需要使用 C::c_func。反过来,经过一些处理后,C 需要在 B 中调用我上面没有指定的回调函数。实际上有两种情况很有趣:

  1. 如果要求 C 不是有状态的 - 那么它需要像上面的代码一样从 A 和 B 接收 BPtr。
  2. 如果 C 是有状态的并且 A 和 B 都实例化了单独的 C 实例,则在 C 的 ctor 中给出一个 BPtr。
4

2 回答 2

10

用这个实例化一个 shared_ptr 可以吗?

不,至少有几个原因:

  1. 如果您在堆栈上或静态创建AB对象,您最终会shared_ptr“拥有”在堆栈上创建的对象;当对象被销毁时,shared_ptr会调用析构函数,调用delete对象,只会发生Bad Things。此外,即使对象是动态创建的,您也无法确定类的所有者可以使用它做什么:他可能会将其分配给其他类型的智能指针,例如 an auto_ptr,它具有完全不同的语义。

  2. 你最终得到一个循环引用。例如,b_ptr拥有B它所属的对象。您必须手动操作.reset()才能B销毁对象。

您可以通过 using获取 a shared_ptrfrom ,但有很多警告:即,您不能调用构造函数。即便如此,您也不希望将 a 存储到对象本身内部的对象中;这没有任何意义。thisenable_shared_from_thisenable_shared_from_thisshared_ptr

我猜我在做一些根本错误的事情。

是的,但是由于您没有确切地说出您要做什么,因此很难说您应该做什么。您只告诉我们您是如何尝试做到这一点的,而不是您一开始想要做什么。

于 2011-01-22T00:22:19.623 回答
0

我建议您重新设计以使用 std::enable_shared_from_this,例如

class B
{
   B();
public:
   std::shared_ptr<B> create() { return std::make_shared<B>(); } // Make sure B is allocated as shared_ptr inorder to ensure that shared_from_this() works.
};

但是,如果这是您遇到的 API 问题,那么您可以执行以下操作(尽管我不推荐这样做)。

void b_func() { C::c_func(BPtr(this, [](B*){})); } // Empty deleter. Nothing happens when shared_ptr goes out of scope. Note that c_func cannot take ownership of the pointer.
于 2011-01-22T00:38:53.177 回答