Boost logo

Boost :

From: Mathias Gaunard (mathias.gaunard_at_[hidden])
Date: 2007-10-06 17:10:52


Vladimir Batov wrote:

> shared_ptr is an extremely versatile and poweful gadget. One (among others)
> thing it handles well is incomplete classes for implementation hiding. Maybe
> there are other smart pointers doing that sort of thing cheaper. I am not
> sure.

Here is a simple deep-copying smart pointer.

template<typename T>
struct copy_ptr
{
     copy_ptr() : ptr(0)
     {
     }

     explicit copy_ptr(T* ptr_) : ptr(ptr_)
     {
     }

     ~copy_ptr()
     {
         delete ptr;
     }

     copy_ptr(const copy_ptr& p) ptr(p.ptr ? new(ptr) T(*p.ptr) : 0)
     {
     }

     copy_ptr& operator=(const copy_ptr& p)
     {
         if(ptr)
         {
             if(p.ptr)
             {
                 *ptr = *p.ptr;
             }
             else
             {
                 delete ptr;
                 ptr = 0;
             }
         }
         else if(p.ptr)
         {
             new(ptr) T(*p.ptr);
         }
     }

     void swap(copy_ptr& p)
     {
         T* tmp = ptr;
         ptr = p.ptr;
         p.ptr = ptr;
     }

     T* operator->()
     {
         return ptr;
     }

     const T* operator->() const
     {
         return ptr;
     }

     T& operator*()
     {
         return *ptr;
     }

     const T& operator*() const
     {
         return *ptr;
     }

     T* get()
     {
         return ptr;
     }

     const T* get() const
     {
         return ptr;
     }

private:
     T* ptr;
};

Could hardly be simpler and more lightweight.
(Well, not allowing null pointers would certainly simplify it actually)

That is nothing compared to the massive overhead of using shared_ptr.

>
>> You want your implementation details to be
>> shared across all 'Test's?
>> What you need is more like a deep-copying smart pointer.
>
> It certainly depends on application. Like if I have a GUI widget, then I do
> not want to deep-copy it. If I have static read-only configuration data, I
> do not want deep-copying those either.
>
> Deep-copying vs. shallow-copying is a separate issue that is likely to be
> addressed via an additional policy template parameter. I did not want to
> blow up my example with all the bells and whistles for smaller code
> foot-print and so that the main idea stands out clearer.

When you copy an object, modifying the copy shouldn't trigger any
visible side-effect in the original one.
That is why sharing implementation details can only be done if data is
read-only.

Thus, shallow-copy certainly cannot be applied by default : it's
implementation dependent ; so it's no good for something that's supposed
to be a generic idiom for implementations.
There is no need for a policy either, since you could just use
shared_ptr in your implementation type if you want something to be
shared and not copied. (that actually gives you more flexibility for the
implementation than setting a policy in the interface, which would set
the ABI)
So you just need a deep-copying smart pointer like the one I provided
earlier.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk