1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class ref_counted 19 { 20 21 protected: ref_counted(void)22 ref_counted( void ) : _count( 0 ) {} 23 24 public: 25 add_ref(void)26 unsigned int add_ref( void ) { return ++_count; } release(void)27 unsigned int release( void ) { return --_count; } count(void)28 unsigned int count( void ) const { return _count; } 29 30 31 protected: 32 unsigned int _count; 33 }; 34 35 36 37 38 39 template < class T > 40 class ref_ptr 41 { 42 43 public: _ptr(ptr)44 ref_ptr( T* ptr = 0 ) : _ptr( ptr ) 45 { 46 add_ref(); 47 } 48 ref_ptr(const ref_ptr & rptr)49 ref_ptr( const ref_ptr & rptr ) : _ptr( rptr.get() ) 50 { 51 add_ref(); 52 } 53 ~ref_ptr(void)54 ~ref_ptr( void ) { release(); } 55 56 get(void)57 T* get( void ) const { return _ptr; } 58 T* operator->( void ) const { return get(); } 59 T& operator*( void ) const { return *get(); } 60 61 bool operator!( void ) const { return get() == 0; } 62 bool operator==( const ref_ptr & rptr ) const { return *get() == *rptr; 63 } 64 bool operator<( const ref_ptr & rptr ) const { return *get() < *rptr; } 65 66 67 bool operator==( T* ptr ) const { return *get() == *ptr; } 68 bool operator<( T* ptr ) const { return *get() < *ptr; } 69 70 const ref_ptr & operator=( const ref_ptr & rptr ) 71 { 72 release(); 73 _ptr = rptr.get(); 74 add_ref(); 75 76 return *this; 77 } 78 79 T* operator=( T* ptr ) 80 { 81 release(); 82 _ptr = ptr; 83 add_ref(); 84 85 return _ptr; 86 } 87 88 protected: add_ref(void)89 void add_ref( void ) 90 { 91 if( _ptr ) 92 _ptr->add_ref(); 93 } 94 release(void)95 void release( void ) 96 { 97 if( _ptr && 0 == _ptr->release() ) 98 { 99 delete _ptr; 100 _ptr = 0; 101 } 102 } 103 104 105 protected: 106 T * _ptr; 107 }; 108 109 110 template< class T > 111 bool operator==( T* ptr, const ref_ptr< T > & rptr ) 112 { 113 return *ptr == *rptr; 114 } 115 116 template< class T > 117 bool operator<( T* ptr, const ref_ptr< T > & rptr ) 118 { 119 return *ptr < *rptr; 120 } 121 122 123 124 class Baz : public ref_counted { 125 int dummy; 126 }; 127 128 129 class Bar; 130 main()131int main() { 132 ref_ptr<Baz> foo; 133 static_cast<Bar *> (foo)->DoSomething; //ERROR - invalid cast 134 } 135