Listing 5
#include <cassert> const bool deletable = true; template<typename T> class new_ptr { public: new_ptr(T* x) : m(x) { }; T* m; }; template<typename T> inline new_ptr<T> new_cast(T* x) { return new_ptr<T>(x); } template<typename T, bool can_delete = false> class ptr { public: ptr() : m(NULL) { }; ptr(const ptr& x) : m(x.m) { }; ptr(T* x) : m(x) { }; ptr(const ptr<T, deletable>& x) : m(x.raw_pointer()) { }; T* operator->() const { return m; } private: T* m; }; template<typename T> class ptr<T, deleteable> { public: ptr() : m(NULL) { }; ptr(const ptr& x) : m(x.m) { }; ptr(const new_ptr<T>& x) : m(x.m) { }; void Delete() { assert(m != NULL); delete m; assert((m = NULL) == NULL); } T* operator->() const { return m; } T* raw_pointer() const { return m; } private: T* m; };