when reading \"Beyond the C++ Standard Library: An Introduction to Boost \" ,I got a very interesting example:
class A
{
public:
virtual void sing()=0;
Surprisingly, the key here is not boost::shared_ptr
destructor but its constructor(s).
If you look into boost/shared_ptr.hpp
, you will see that shared_ptr<T>
does not 'simply' have a constructor expecting a T *
but :
template<class Y>
explicit shared_ptr( Y * p );
In //3
when you construct a boost::shared_ptr
from a B *
, no conversion to A *
takes place, and the shared_ptr
internals are built with the actual B
type. Upon destruction of the object, deletion occurs on a B
pointer (not through a base class pointer).
The shared_ptr
class template has a member of class type shared_count
, which in turn has a member of type pointer to class sp_counted_base
. The constructor template for class shared_count
assigns a pointer to an instance of the class template sp_counted_impl_p
to this member which is templated by the type of the constructor argument, not by the shared_ptr::value_type
. sp_counted_base
has a pure virtual member function dispose
which is overwritten by sp_counted_impl_p
. Because sp_counted_impl_p
knows the type B
in your example, it can delete it without access to the base class destructor, and because it uses virtual dispatch, the type is determined at runtime. This method requires a combination of parametric and subtype polymorphism.