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()131 int main() {
132   ref_ptr<Baz> foo;
133   static_cast<Bar *> (foo)->DoSomething;  //ERROR - invalid cast
134 }
135