Using boost::shared_ptr on class hierarchies
boost::shared_ptr
has become one of the most versatile smart_pointer structures used in C++.
If you consistently use shared_ptr
to refer to objects,
you don’t have to worry when to destroy them.
We would like to see how boost::shared_ptr
can be used amidst up-casting and down-casting across class hierarchies.
Consider the following class.
class A { public: A():m_i(0){} virtual ~A(){} int m_i; };
If we always use boost::shared_ptr
-s to refer to an instance of A, we
can use them across scopes, worry free of when to destroy them as shown.
using namespace boost; shared_ptr <A> sA1; { shared_ptr <A> sA2( new A); sA1 = sA2; //sA1 and sA2 shares the same pointer to A //and the same reference counting structure assert( sA1.use_count() == sA2.use_count() ); assert( sA1.use_count() == 2); } assert( sA1.use_count() == 1);
Now, let B
, be a derived class of A
as shown below.
</pre> class B : public A { public: B():m_j(0){} ~B(){} int m_j; }; </pre>
shared_ptr and up-casting
If we assign a shared_ptr
B
to a shared_ptr
A
,
the two shared pointers still share the same pointer and the reference count. So shared_pointer
respects up-casting. Please see the code below.
using namespace boost; shared_ptr <A> sA; { shared_ptr <B> sB( new B); sA = sB; //sA and sB shares the same pointer to B //and the same reference counting structure assert( sA.use_count() == sB.use_count() ); assert( sA.use_count() == 2); } assert( sA.use_count() == 1);
shared_ptr and down-casting
Now consider the problem of down-casting.
using namespace boost; shared_ptr <B> sB; { shared_ptr <A> sA( new B); //how can we reset sB with the pointer //now owned by sA.? }
The following wont compile.
using namespace boost; shared_ptr <B> sB; { shared_ptr <A> sA( new B); //compilation error in the line below sB = sA; }
Here is another wrong way, that results in run-time error.
using namespace boost; shared_ptr <B> sB; { shared_ptr <A> sA( new B); B * pB = dynamic_cast <B*> (sA.get()); sB.reset( pB ); //though sA and sB now points to the same //instance of B, they are reference counted //using different structures. assert( sA.use_count() == 1); assert( sB.use_count() ==1); } //Instance of B pointed to by sA is destroyed. //But hey, sB still refers to it. //Now, the following will cause a runtime error //due to double deletion sB.reset();
The correct way is shown below.
using namespace boost; shared_ptr <B> sB; { shared_ptr <A> sA( new B); sB = dynamic_pointer_cast <B,A> ( sA ) ; //sA and sB now shares the same instance of B. //Further sA and sB shares the same reference //counting structure. assert( sA.use_count() == 2); assert( sB.use_count() == 2); } assert( sB.use_count() == 1);
blog comments powered by Disqus