.TH "smart_pointer" 7rheolef "Sat Mar 13 2021" "Version 7.1" "rheolef" \" -*- nroff -*- .ad l .nh .SH NAME smart_pointer \- with true copy semantic (rheolef-7\&.1) .PP .SH "DESCRIPTION" .PP 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 \fIsmart pointer\fP method for managing memory\&. .PP The true semantic copy is defined as follows: if an object \fCA\fP is assigned to \fCB\fP, such as \fCA = B\fP, every further modification on \fCA\fP or \fCB\fP does not modify the other\&. .PP Notice that this class differs from the \fCstd::shared_ptr\fP class that implements safe pointers without the true copy semantic\&. .SH "CLONE VARIANT" .PP The \fBsmart_pointer_clone\fP variant uses a \fCT* T::clone() const\fP member function instead of the usual \fCT::T()\fP 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\&. .PP 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\&. .SH "NOCOPY VARIANT" .PP The \fBsmart_pointer_nocopy\fP 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 \fBsmart_pointer_nocopy\fP\&. This ensures that the file handle cannot be copied and is closed when the last alias is destroyed\&. .PP The interface to the nocopy variant is the same as \fBsmart_pointer\fP 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\&. .PP The following modifiers cannot be used because they use copying of the pointed-to object and will therefore cause an error: .PP .nf T* operator-> (); T& operator* (); T* pointer (); T& data (); .fi .PP .SH "REFERENCE" .PP [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 .SH "EXAMPLE" .PP .PP .nf // 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 { 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 (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; } .fi .PP .SH "IMPLEMENTATION" .PP This documentation has been generated from file util/lib/smart_pointer\&.h .PP .PP .nf template class smart_pointer : public smart_pointer_base > { typedef details::constructor_copy C; typedef smart_pointer_base 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& x) : base(x) {} smart_pointer& operator= (const smart_pointer& x) { base::operator= (x); return *this; } ~smart_pointer() {} }; .fi .PP .PP .nf template class smart_pointer_clone : public smart_pointer_base > { typedef details::clone_copy C; typedef smart_pointer_base 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& x) : base(x) {} smart_pointer_clone& operator= (const smart_pointer_clone& x) { base::operator= (x); return *this; } ~smart_pointer_clone() {} }; .fi .PP .PP .nf template class smart_pointer_nocopy : public smart_pointer_base > { typedef details::no_copy C; typedef smart_pointer_base 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& x) : base(x) {} smart_pointer_nocopy& operator= (const smart_pointer_nocopy& x) { base::operator= (x); return *this; } ~smart_pointer_nocopy() {} }; .fi .PP .SH AUTHOR Pierre Saramito .SH COPYRIGHT Copyright (C) 2000-2018 Pierre Saramito GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.