简体   繁体   English

适当用于boost :: shared_ptr?

[英]Appropriate use for boost::shared_ptr?

A question about boost::shared_ptr here: 关于boost::shared_ptr问题:

I have 3 Classes. 我有3个课程。

A is some kind of Main class which is responsible to manage everything. A是某种Main类,负责管理一切。

B is a class which just has functions to do some work. B是一个只具有完成某些工作的功能的类。

Dispatcher is just a class which wraps around a seperate thread, which gets the work from Instaces of B done in this thread. Dispatcher只是一个包装单独线程的类,它从这个线程中的B Instaces获得工作。

So it is kinda working like this: A has an instance of Dispatcher . 所以它有点像这样工作: A有一个Dispatcher实例。 Now on occassion A generates an instance of B and passes it to the dispatcher. 现在,在场合A生成B的实例并将其传递给调度员。

The important part is, that B needs to call A::callback() when it's done. 重要的是, B需要调用A::callback() This is why B gets a reference to A in it's constructor ( see code below ) 这就是B在它的构造函数中获取对A的引用的原因(参见下面的代码)

A.hpp A.hpp

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

B.hpp B.hpp

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

Dispatcher.hpp Dispatcher.hpp

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

A.cpp 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.cpp

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

main_example.cpp main_example.cpp

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

So my question is: 所以我的问题是:

Is it reasonable to use boost::shared_ptr for this purpose? 为此目的使用boost :: shared_ptr是否合理?

I am not sure if the shared_ptr is the right thing to go here. 我不确定shared_ptr是否适合去这里。 My problem is, that I don't know what happens exactly when I call the constructor from B and pass it the this pointer. 我的问题是,当我从B调用构造函数并将其传递给this指针时,我不知道究竟发生了什么。 Now according to shared_ptr I would assume that m_PointerToA takes ownership of A . 现在根据shared_ptr我会假设m_PointerToA取得A所有权。 But this would mean that when the work in the Dispatcher is done and my instance of B gets deleted it would also delete the reference to m_PointerToA which would actually mean it kills the object itself despite the fact there is an actual instance of A in the main loop. 但这意味着当Dispatcher中的工作完成并且我的B实例被删除时,它也会删除对m_PointerToA的引用,这实际上意味着它会杀死对象本身,尽管事实上主要有A实例环。

Update: 更新:

Added some code and updated question itself to make it more clear. 添加了一些代码和更新的问题本身,以使其更清晰。

There's nothing particular wrong with this design. 这种设计没有什么特别的错误。 However I would prefer to instead use boost::function<> & boost::bind . 但是我宁愿使用boost::function<>boost::bind It gives you way better flexibility for the callback and doesn't tie B as tightly to A. Of course you still have to be vary of the usual threading caveats. 它为回调提供了更好的灵活性,并且不会将B紧密地绑定到A.当然,您仍然需要改变通常的线程警告。

Yes, it is okay to just copy/assign a shared_ptr , it will only increase the reference count. 是的,可以只复制/分配shared_ptr ,它只会增加引用计数。

In your example, shared_from_this() will create a (here: temporary) shared_ptr from the weak_ptr that is hold by this (ref count 1), so when you assign/copy-construct m_PointerToA , the reference count will increase temporarily to 2 before the ctor returns and the temporary object will be destroyed, decreasing the reference count to 1 again (the shared_ptr is "aware" of the one instance in your B object). 在你的榜样, shared_from_this()将创建一个:(这里暂时) shared_ptrweak_ptr是通过持有this (引用计数1),所以当你分配/拷贝构造m_PointerToA ,引用计数会前临时增加至2 ctor返回并且临时对象将被销毁,再次将引用计数减少到1(shared_ptr“知道” B对象中的一个实例)。

So, yes, if B is deleted, it will destroy A in this case (as the reference count drops to 0). 所以,是的,如果B被删除,它将在这种情况下销毁A(因为引用计数降为0)。

Your concern 你所关心的

This would mean if my Instance of B is deleted, it would also delete m_PointerToA which would also kill my instance of A . 这意味着如果我的B实例被删除,它也会删除m_PointerToA,这也会杀死我的A实例。 Of course my original instance of A is held elsewhere. 当然,我原来的A实例是在其他地方举行的。

only shows that if you plan/need/intend to keep a pointer to the instance of A for further usage, you should do so with a shared_ptr as well instead of a raw pointer. 只显示如果您计划/需要/打算保留指向A实例的指针以供进一步使用,您应该使用shared_ptr而不是原始指针。 If you have control of A 's interface, the easiest way would be a named constructor like this: 如果您可以控制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() );
}

Then, even if your instance of B is deleted, the instance of A will still survive because the reference count of the shared_ptr is still (at least) 1. 然后,即使您的B实例被删除, A的实例仍然存在,因为shared_ptr的引用计数仍然(至少)为1。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM