Re: A situation where private inheritance is useful
Hi,
Juha Nieminen wrote:
Suppose you want to create an intrusive smart pointer which supports
specifying which memory allocator was used to allocate the object being
managed (so that the smart pointer will be able to destroy the object
using that same memory allocator). A naive implementation could look
something like this:
template<typename Obj_t, typename Allocator = std::allocator<Obj_t> >
class IntrusivePtr
{
Obj_t* obj;
Allocator allocator;
public:
// All the necessary public methods here
};
The class has to store the allocator object (which it has to take eg.
as a constructor parameter) because it is possible for allocators to
have an internal state, and if this is so, it must be stored so that the
object can be destroyed appropriately. You cannot simply assume you can
instantiate the allocator whenever it's needed (this could work with
stateless allocators but not with ones with an internal state).
I usually do not implement my smart pointers this way. I usually have an
abstract base class (without virtual functions, but unusable) and I
handle the deallocation in derived classes. This gives you almost all
options. The disadvantage is that the derived classes have to enrich
more than one function of the base class with the deallocation call. But
the performance at runtime is very good. A second advantage is that the
base class or at least any non-trivial part of it can be of non-template
type. This is achieved by storing void* internally. The reinterpret cast
from void* to exactly the same type where it came from is known to be
safe and does not generate any executable code, and all of that is
encapsulated in the type safe template wrapper. This can significantly
decrease the executable size and therefore improve the cache
efficiencies, if the smart pointers are used for many different types.
But of course, the private inheritance is another solution. It only
generates more code.
Marcel