oracular (7) smart_pointer.7rheolef.gz

Provided by: librheolef-dev_7.2-3build5_amd64 bug

NAME

       smart_pointer - with true copy semantic (rheolef-7.2)

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 std::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 localized to the
       individual subclass.

NOCOPY VARIANT

       The smart_pointer_nocopy variant 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
       therefore cause an error:

           T* operator-> ();
           T& operator* ();
           T* pointer ();
           T& data ();

REFERENCE

       [1] A. Geron and F. Tawbi, Pour mieux developer avec C++ : design pattern, STL, RTTI et smart pointers,
       InterEditions, 1999. Page 118. [2] STLplus: clone and nocopy variants,
       http://stlplus.sourceforge.net/stlplus3/docs/smart_ptr.html

EXAMPLE

       // data representation (could be file "container_data.h")
       typedef int T;
       class container_data {
           private:
               T *values;
               int n;
           public:
               container_data (const container_data& x)
                : values(new T[x.n]), n(x.n)
               { for (int i=0; i<n;i++) values[i]=x.values[i];}
               container_data& operator= (const container_data& x) {
                 n = x.n;
                 values = new T[n];
                 for (int i=0; i<n;i++) values[i]=x.values[i];
                 return *this;
               }
               // a customized constructor
               explicit container_data(int n1)
                : values(new T[n1]), n(n1) {}

               ~container_data() { delete [] values; }

               // read and write accessors are separated
               const T& operator[](int i) const
                           { return values[i]; }
                     T& operator[](int i)
                           { return values[i]; }
       };
       // an interface to data via the Objet class
       //        that count occurrence (could be "container.h")
       //
       class container : private smart_pointer<container_data> {
       public:
           // the customized cstor
           explicit container(int n = 0);

           // read/write accessors
           const T&  operator[](int i) const;
                 T&  operator[](int i);
       };
       // here is the implementation of the interface
       //  (could be "container.c")
       //
       container::container (int n)
       : smart_pointer<container_data> (new container_data(n))
       {}
       const T&
       container::operator[] (int i) const {
           // use read access data()
           return data().operator[] (i);
       }
       T&
       container::operator[] (int i) {
           // use write access data() that check occurrence count
           return data().operator [] (i);
       }
       // test program
       int main() {
           container A(10);
           A[1] = 1;
           container B = A;
           B[1] = 2;
           if (A[1] == B[1]) {
                   std::cerr << "fatal: It is not a true copy semantic." << std::endl;
               exit(1);
           }
           std::cerr << "It seems to be a true copy semantic." << std::endl;
       }

IMPLEMENTATION

       This documentation has been generated from file util/lib/smart_pointer.h

       template <typename T>
       class smart_pointer : public smart_pointer_base<T, details::constructor_copy<T> > {
           typedef details::constructor_copy<T>     C;
           typedef smart_pointer_base<T,C>          base;
         public:
           typedef T                                handled_type;
           typedef typename base::internal          internal;
           smart_pointer (T* p = 0) : base (p) {}
           smart_pointer (void* count, internal i) : base(count,i) {}
           smart_pointer (const smart_pointer<T>& x) : base(x) {}
           smart_pointer<T>& operator= (const smart_pointer<T>& x) {
               base::operator= (x); return *this; }
           ~smart_pointer() {}
       };

       template <typename T>
       class smart_pointer_clone : public smart_pointer_base<T, details::clone_copy<T> > {
           typedef details::clone_copy<T>     C;
           typedef smart_pointer_base<T,C>    base;
         public:
           typedef T                          handled_type;
           typedef typename base::internal    internal;
           smart_pointer_clone (T* p = 0) : base (p) {}
           smart_pointer_clone (void* count, internal i) : base(count,i) {}
           smart_pointer_clone (const smart_pointer_clone<T>& x) : base(x) {}
           smart_pointer_clone<T>& operator= (const smart_pointer_clone<T>& x) {
               base::operator= (x); return *this; }
           ~smart_pointer_clone() {}
       };

       template <typename T>
       class smart_pointer_nocopy : public smart_pointer_base<T, details::no_copy<T> > {
           typedef details::no_copy<T>        C;
           typedef smart_pointer_base<T,C>    base;
         public:
           typedef T                          handled_type;
           typedef typename base::internal    internal;
           smart_pointer_nocopy (T* p = 0) : base (p) {}
           smart_pointer_nocopy (void* count, internal i) : base(count,i) {}
           smart_pointer_nocopy (const smart_pointer_nocopy<T>& x) : base(x) {}
           smart_pointer_nocopy<T>& operator= (const smart_pointer_nocopy<T>& x) {
               base::operator= (x); return *this; }
           ~smart_pointer_nocopy() {}
       };

AUTHOR

       Pierre  Saramito  <Pierre.Saramito@imag.fr>

       Copyright   (C)  2000-2018  Pierre  Saramito  <Pierre.Saramito@imag.fr> GPLv3+: GNU GPL version 3 or
       later  <http://gnu.org/licenses/gpl.html>.  This  is  free  software:  you  are free to change and
       redistribute it.  There is NO WARRANTY, to the extent permitted by law.