Appropriate use for boost :: shared_ptr?

The question about boost::shared_ptr here:

I have 3 classes.

A is some kind of main class that is responsible for everything.

B is a class that only has functions to do some work.

Dispatcher is just a class that wraps around a separate thread that receives work from the B instances executed on that thread.

So it works as follows: A has an instance of Dispatcher . Now, in case A , an instance of B is created and passed to the dispatcher.

The important part is that B needs to call A::callback() when this is done. This is why B gets a reference to constructor A in it (see code below)

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 */ }; 

Dispatcher.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; } 

So my question is:

Is it possible to use boost :: shared_ptr for this purpose?

I'm not sure if this is shared_ptr right. My problem is that I do not know what happens when I call the constructor from B and pass the this pointer to this . Now according to shared_ptr I would suggest that m_PointerToA has ownership of A But that would mean that when Dispatcher was done and my instance of B was deleted, it would also delete the m_PointerToA link, which actually means that it kills the object itself, despite the fact that there is a real instance of A basically cycle.

Update:

The code has been added and the question itself has been updated to make it more understandable.

+4
source share
2 answers

Yes, it is just copy / assign shared_ptr , it will only increase the number of links.

In your example, shared_from_this() will create a (here: temporary) shared_ptr from weak_ptr that is held by this (ref count 1), so when you assign / copy -construct m_PointerToA , the reference count will temporarily increase to 2 until ctor returns, and the temporary the object will be destroyed, the reference counter will decrease again to 1 (shared_ptr "knows" one instance of your object B ).

So, yes, if B is deleted, it will destroy A in this case (when the reference count drops to 0).

Your concern

This means that if my instance of B is deleted, it will also delete m_PointerToA, which will also kill my instance of A. Of course, my original instance of A is located elsewhere.

shows that if you plan / need / intend to save a pointer to an instance of A for future use, you should do this with shared_ptr , and not with a raw pointer. If you have control over interface A , the easiest way would be a named constructor as follows:

 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, instance A will still be saved, because the shared_ptr reference count is still (at least).

+1
source

There is nothing special about this design. However, I would rather use boost::function<> and boost::bind instead. This gives you better flexibility to call back and does not bind B as well as A. Of course, you should still be different regular firmwares.

+4
source

Source: https://habr.com/ru/post/1403450/


All Articles