/// creation policy template < typename T > struct new_create { typedef T pointee_type; typedef T* pointer_type; typedef T* redirect_pointer_type; static void T* create() { return new T(); } static void destroy(T* t) { delete t; } }; /// creation policy template < typename T > struct custom_create { typedef T pointer_type; typedef T::pointee_type pointee_type; typedef T::redirect_pointer_type redirect_pointer_type; static T create() { T c; c.create(); return c; } static void destroy(T t) { t.destroy() ; } }; /// functions common to all ptrs template < class PT, class RPT, class PTE > class pointer_base { public: typedef PT pointer_type; typedef RPT redirect_pointer_type; typedef PTE pointee_type; pointer_base(pointer_type& p ) : ptr_(p) { } pointee_type operator*() { return *ptr_; } redirect_pointer_type operator->() { return ptr_.operator->() } pointer_type& ptr() { return ptr_; } private: pointer_type ptr_; }; /// template < class T, class CP = new_create // creation policy > class scoped_ptr : public pointer_base public: scoped_ptr() : pointer_base(CP::create()) { } ~scoped_ptr() { CP::destroy(ptr()); } private: scoped_ptr(const scoped_ptr&); scoped_ptr& operator=(); }; /// each gets its own copy template < class T, class CP = new_create > class copy_ptr : pointer_base { public: copy_ptr() { } : pointer_base(CP::create()) { } copy_ptr(const copy_ptr& other) : pointer_base(CP::create()){ *(ptr()) = *(other.ptr()); } ~copy_ptr() { CP::destroy(ptr()); } copy_ptr& operator=(const copy_ptr& other) { if(&other == this) return *this; *(ptr()) = *(other.ptr()) ; return *this; } }; /// uses destructive copy like std::auto_ptr template < class T, class CP = new_create > class auto_ptr : pointer_base { public: auto_ptr() : pointer_base(CP::create()) { } auto_ptr(const auto_ptr& other) { other.ptr() = 0; } ~auto_ptr() { CP::destroy(ptr()); } auto_ptr& operator=(const auto_ptr& other) { if(&other == this) return *this; CP::destroy(ptr()); ptr() = other.ptr() ; other.ptr() = 0; return *this; } }; /// refcounted template < class T, class CP = new_create, class Index = int, class ICP = new_delete > class refcount_ptr : pointer_base { public: refcounted_ptr() : pointer_base(CP::create(), index_ptr(ICP::create()) { *index_ptr = 1; } refcounted_ptr(const refcounted_ptr& cpy) : index_ptr(cpy.index_ptr) { (*index_ptr)++; } ~refcounted_ptr() { if(--(*index_ptr) == 0 ) { CP::destroy(ptr()); ICP::destroy(index_ptr); } } refcounted_ptr& operator=(const refcounted_ptr& other) { if(this == &other) return *this; if(--(*index_ptr) == 0) { ICP::destroy(index_ptr); CP::destroy(ptr()); } ptr() = other.ptr(); index_ptr = other.index_ptr; (*index_ptr)++; return *this; } int use_count() { return int(*index_ptr) ; } private: ICP::pointer_type index_ptr; };