C++ Boost::使用此

C++ Boost::使用此,c++,this,shared-ptr,multiple-instances,C++,This,Shared Ptr,Multiple Instances,考虑以下情况: 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

考虑以下情况:

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) { /*...*/ }
}
typedef boost::shared_ptr BPtr;
甲级
{
公众:
A(){b_ptr=BPtr(新b);}
void a_func(){C::C_func(b_ptr);}
私人:
BPtr b_ptr;
}
B类
{
公众:
B(){B_ptr=BPtr(this);}
void b_func(){C::C_func(b_ptr);}
私人:
BPtr b_ptr;
}
C类
{
公众:
静态void c_func(BPtr b_ptr){/*…*/}
}
这个
实例化一个共享的\u ptr可以吗?
两个共享的_ptr对象指向同一个对象可以吗?(例如A::b_ptr和b::b_ptr)
如果这两个实例中有一个超出范围,B的实例会被删除吗

我猜我在做一些根本错误的事情。
我还考虑过将b_ptr的依赖注入到b的构造函数中,但这似乎也是非常错误的

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

  • 如果要求C不是有状态的,那么它需要从a和B接收BPtr,如上面的代码所示
  • 如果C是有状态的,并且A和B都实例化了单独的C实例,则在C的ctor中给出一个BPtr
  • 可以用这个来实例化一个共享的ptr吗

    不,至少有几个原因:

  • 如果您在堆栈上或静态地创建
    a
    B
    对象,那么您最终将拥有一个
    共享的\u ptr
    “拥有”在堆栈上创建的对象;当对象被销毁时,将调用
    shared_ptr
    析构函数,对对象调用
    delete
    ,只会发生不好的事情。此外,即使对象是动态创建的,您也无法确定类的所有者会对其做什么:他可能会将其分配给其他类型的智能指针,例如具有完全不同语义的
    auto_ptr

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


  • 通过使用
    enable\u shared\u from\u this
    ,您可以从
    this
    获取
    shared\u ptr,但是有很多警告:即,您不能在构造函数中调用
    enable\u shared\u from\u this
    。即使如此,您也不希望将
    共享的\u ptr
    存储到对象本身内部的对象;这没有任何意义

    我猜我做错了什么


    是的,但是因为你没有说你到底想做什么,所以很难说你应该做什么。您只告诉了我们您是如何做到这一点的,而没有告诉我们您首先要做什么。

    我建议您重新设计,使用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.
    };
    

    我给你打分,但我有点不同意。如果说用
    this
    实例化
    共享\u ptr
    是不合适的,则意味着
    启用\u shared\u from\u this
    不应该存在,这是错误的。这里的错误在于,将
    共享的ptr
    作为成员变量设置为
    这个
    是不合适的。@Omnifarious:我想我说的是正确的:你永远不应该(至少明确地)用
    这个
    实例化一个新的
    共享的ptr
    对象;这样做要么大错特错,要么大错特错。您可以使用安全库提供的工具
    从\u this
    启用\u shared\u隐式执行此操作。不过,我几乎可以肯定OP询问的是显式形式。
    enable\u shared\u from\u此
    要求在使用前通过“普通”方式创建一个
    shared\u ptr
    ,注意。@Jonathan:
    C
    确实需要拥有
    B
    对象吗?它是否必须采取
    共享\u ptr
    ?可能需要a
    B&
    来代替吗?C只需要在B中调用回调,我想引用就可以了。我试试看
    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.