tags:

views:

32

answers:

1

I'm following an example in Accelerated C++ and writing a simple Handle class that will act as a smart pointer. This uses the virtual ctor idiom using a virtual clone() function. So far so good. But what to do when I want to use my Handle for classes that I don't control that don't provide clone()?

The method suggested in the book is to create a global clone function and use template specialization (something I'm seeing for the first time) so that if clone() is called with a particular argument, one can write code to handle that case.

My question is: This means that I have to write a clone() version for every type of class that I envision my user can use Handle with. This seems quite hard! Is there a more elegant and/or simple way to solve this issue? How is it possible that things like auto_ptr or boost::shared_ptr are able to provide this functionality without the tedious clone() definitions?

For completeness, here's my Handle class implementation:

template <class T> class Handle
{
public:
    Handle() : p(0) {}
    Handle(T* t) : p(t) {}
    Handle( const Handle& s ) :p(0) { if (s.p) p = s.p->clone(); }
    const Handle& operator=( const Handle& );
    ~Handle() { delete p; }

    operator bool() { return p; }

    T& operator*() { if (p) return *p; else throw std::runtime_error("Handle not bound"); }
    T* operator->() { if (p) return p; else throw std::runtime_error("Handle not bound"); }
private:
    T* p; 
};

Thanks!

+2  A: 

The solution to this problem is to simply not write Handles for these kinds of classes. No. Really.

auto_ptr never needs to clone the underlying object, because auto_ptr never copies the object. An auto_ptr only ever has one copy of the object, and when the auto_ptr is copied, control of the object is transfered -- that object is not copied.

shared_ptr never needs to clone because it also only ever controls one copy of the object. Copying the shared_ptr only increments the reference count, and that single object is destroyed when the reference count is zero.

In general, if there's no way to deep copy the resource your class is controlling, then you should just make the class noncopyable. If clients need to pass references to your class around, they can place the class in an auto_ptr or shared_ptr themselves.

Billy ONeal