Appropriate use for boost::shared_ptr?

Appropriate use for boost::shared_ptr?

本文关键字:ptr shared Appropriate for boost use      更新时间:2023-10-16

关于boost::shared_ptr的问题:

我有三节课。

A是一种Main类,它负责管理一切。

B是一个类,它只具有做一些工作的函数。

Dispatcher只是一个包裹在一个单独线程周围的类,它在这个线程中完成了B的Instaces的工作。

所以它是这样工作的:A有一个Dispatcher的实例。现在,A偶尔会生成B的一个实例,并将其传递给调度器。

重要的是,B需要在完成后调用A::callback()。这就是B在其构造函数中引用a的原因(参见下面的代码)

A.hpp

class A : public boost::enable_shared_from_this<A>
{
public:
    A();
    void sendB();
    void callback();
private:
    Dispatcher m_Dispatcher;
};

B.hpp

class B
{
public:
    B(boost::shared_ptr<A> ptr);
    boost::shared_ptr<A> m_PointerToA;
 /* Some other functions */
};

调度员.hpp

class Dispatcher
{
public:
     void run();
     void dispatch(boost::shared_ptr<B> b);
private:
     void doWork();
     boost::thread m_Thread;  
};

A.cpp

A::A()
{
    m_Dispatcher.run();
}
void A::sendB()
{
    boost::shared_ptr ptr_B;
    ptr_B.reset(new B(this->shared_from_this);
    m_Dispatcher.dispatch(ptr_B);
}

B.cpp

B::B(boost::shared_ptr<A> ptr) :
    : m_PointerToA(ptr)
{
}

main_example.cpp

int main()
{
     A instanceA;
     while(true)
     {
          instanceA.sendB();
          /* Do some other stuff */
     }
     return 0;
}

所以我的问题是:

为此目的使用boost::shared_ptr合理吗

我不确定shared_ptr在这里是否合适。我的问题是,当我从B调用构造函数并将this指针传递给它时,我不知道会发生什么。现在,根据shared_ptr,我假设m_PointerToA拥有A的所有权。但这意味着,当Dispatcher中的工作完成,并且我的B实例被删除时,它也会删除对m_PointerToA的引用,这实际上意味着它会杀死对象本身,尽管主循环中有A的实际实例。

更新:

添加了一些代码并更新了问题本身,使其更加清晰。

这个设计没有什么特别的问题。然而,我更喜欢使用CCD_ 23&boost::bind。它为回调提供了更好的灵活性,并且不会将B与A紧密联系在一起。当然,您仍然需要注意不同的常见线程注意事项。

是的,只复制/分配一个shared_ptr是可以的,它只会增加引用计数。

在您的示例中,shared_from_this()将从this持有的weak_ptr创建一个(此处:临时)shared_ptr(引用计数1),因此当您分配/复制构造m_PointerToA时,在ctor返回之前,引用计数将临时增加到2,临时对象将被销毁,再次将引用计数减少到1(shared_ptr"知道"B对象中的一个实例)。

所以,是的,如果B被删除,它将在这种情况下销毁A(因为引用计数降至0)。

您关心的

这意味着,如果我的B实例被删除,它也会删除m_PointerToA,这也会杀死我的A实例。当然,我最初的A实例在其他地方。

仅显示,如果您计划/需要/打算保留指向A实例的指针以供进一步使用,则也应该使用shared_ptr而不是原始指针。如果您可以控制A的接口,那么最简单的方法就是使用这样的命名构造函数:

class A : public boost::enable_shared_from_this<A> {
    public:
        static boost::shared_ptr<A> create();
        void initClassB();
        // ....
    private:
        A();
        A( const A & other );
        A& operator=( const A & rhs );
};
boost::shared_ptr<A> A::create() {
    return boost::shared_ptr<A>( new A() );
}

然后,即使B的实例被删除,A的实例仍将存在,因为shared_ptr的引用计数仍然(至少)为1。