适当用于boost :: shared_ptr?

时间:2012-03-26 12:02:13

标签: c++ pointers boost shared-ptr

关于boost::shared_ptr的问题:

我有3个课程。

A是某种Main类,负责管理所有内容。

B是一个只具有完成某些工作的功能的类。

Dispatcher只是一个包含一个单独线程的类,它从这个线程中的B的Instaces获得工作。

所以它的工作方式如下:A的实例为Dispatcher。现在,A生成B的实例并将其传递给调度员。

重要的是,B需要在A::callback()完成后调用B。这就是class A : public boost::enable_shared_from_this<A> { public: A(); void sendB(); void callback(); private: Dispatcher m_Dispatcher; }; 在其构造函数中获取对A的引用的原因(参见下面的代码)

A.hpp

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

B.hpp

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

Dispatcher.hpp

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);
}

A.cpp

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

B.cpp

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

main_example.cpp

shared_ptr

所以我的问题是:

为此目的使用boost :: shared_ptr是否合理?

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

更新

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

2 个答案:

答案 0 :(得分:4)

这种设计没有什么特别的错误。不过我更愿意使用boost::function<>&amp; boost::bind。它为回调提供了更好的灵活性,并且不会将B紧密地绑定到A.当然,您仍然需要改变常见的线程警告。

答案 1 :(得分:1)

是的,只需复制/分配shared_ptr即可,只会增加引用次数。

在您的示例中,shared_from_this()将从shared_ptr {引用weak_ptr(引用计数1)创建一个(此处:临时)this,所以当您assign / copy-construct m_PointerToA,引用计数将在ctor返回之前暂时增加到2,临时对象将被销毁,再次将引用计数减少到1(shared_ptr是&#34;意识到&#34;您B对象中的一个实例。

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

您的关注

  

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

仅显示如果您计划/需要/打算保留指向A实例的指针以供进一步使用,您应该使用shared_ptr而不是原始指针。如果您可以控制A的界面,最简单的方法是named constructor,如下所示:

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。