NAME¶
smart_pointer,
smart_pointer_clone - reference counted safe
pointer with true copy semantic
DESCRIPTION¶
Here is a convenient way to implement a true copy semantic, by using shallow
copies and reference counting, in order to minimise memory copies. This
concept is generally related to the
smart pointer method for managing
memory.
The true semantic copy is defined as follows: if an object
A is assigned
to
B, such as
A = B, every further modification on
A or
B does not modify the other.
Notice that this class differs from the
boost::shared_ptr class that
implements safe pointers without the true copy semantic.
CLONE VARIANT¶
The
smart_pointer_clone variant uses a
T* T::clone() const member
function instead of the usual
T::T() copy constructor for obtaining a
true copy of the data. This variant is motivated as follows: when using
hierarchies of derived classes (also known as polymorphic classes), the usual
copy is not possible because c++ copy constructors cannot be virtual, so you
cannot make a copy this way. This is a well-known problem with C++'s
implementation of polymorphism.
We uses a solution to the non-virtual copy constructor problem which is
suggested by Ellis and Stroustrup in "The Annotated LRM". The
solution is to require the
T class to provide a virtual clone method
for every class which makes a copy using new and the correct copy constructor,
returning the result as a pointer to the superclass
T. Each subclass of
T overloads this function with its own variant which copies its own
type. Thus the copy operation is now virtual and furthermore is localised to
the individual subclass.
NOCOPY VARIANT¶
This variant of the smart pointer is designed for use on objects that cannot (or
must not) be copied. An example would be when managing an object that
contains, say, a file handle. It is essential that this not be copied because
then you get the problem of deciding which copy is responsible for closing the
file. To avoid the problem, wrap the file handle in a class and then manage a
unique instance of it using a
smart_pointer_nocopy. This ensures that
the file handle cannot be copied and is closed when the last alias is
destroyed.
The interface to the nocopy variant is the same as
smart_pointer but with
all operations that perform copying forbidden. In fact, because all three
variants are instances of a common superclass, the forbidden methods do exist
but will cause an error and exit if they are called.
The following modifiers cannot be used because they use copying of the
pointed-to object and will thereore cause an error:
T* operator-> ();
T& operator* ();
T* pointer ();
T& data ();
EFERENCES¶
[1] A. Geron and F. Tawbi,
Pour mieux developper avec C++ : design pattern, STL, RTTI et smart pointers,
InterEditions, 1999. Page 118.
[2] STLplus, http://stlplus.sourceforge.net/stlplus3/docs/smart_ptr.html
for the clone and nocopy variants.
IMPLEMENTATION¶
template <class T, class C>
class smart_pointer_base {
public:
// allocators:
smart_pointer_base (T* p = 0);
smart_pointer_base (const smart_pointer_base<T,C>&);
smart_pointer_base<T,C>& operator= (const smart_pointer_base<T,C>&);
~smart_pointer_base ();
// accessors:
const T* pointer () const;
const T& data () const;
const T* operator-> () const;
const T& operator* () const;
// modifiers:
T* pointer ();
T& data ();
T* operator-> ();
T& operator* ();
// implementation:
private:
struct counter {
T* _p;
int _n;
counter (T* p = 0);
~counter ();
int operator++ ();
int operator-- ();
};
counter *_count;
#ifndef TO_CLEAN
public:
int reference_counter() const { return _count != 0 ? _count->_n : -1; }
#endif // TO_CLEAN
};