]>
Dogcows Code - chaz/yoink/blob - src/stlplus/containers/smart_ptr.hpp
1 #ifndef STLPLUS_SMART_PTR
2 #define STLPLUS_SMART_PTR
3 ////////////////////////////////////////////////////////////////////////////////
5 // Author: Andy Rushton
6 // Copyright: (c) Southampton University 1999-2004
7 // (c) Andy Rushton 2004 onwards
8 // License: BSD License, see ../docs/license.html
10 // A smart pointer is a memory-managing pointer to an object. If you like, it
11 // is a zero-dimensional container.
13 // Assignment of smart pointers result in multiple aliases of the same object.
14 // The term alias is used to differentiate from conventional pointers because
15 // the semantics are different.
17 // Aliases can be turned into copies if the pointed-to class supports copying.
19 // The base class is smart_ptr_base which defines the common interface. Then
20 // there are three subclasses which have the same interface but different copy
23 // - smart_ptr for simple types and classes which have copy constructors
24 // - smart_ptr_clone for polymorphic class hierarchies which are copied using a clone method
25 // - smart_ptr_nocopy for any class that cannot or should not be copied
27 ////////////////////////////////////////////////////////////////////////////////
28 #include "containers_fixes.hpp"
29 #include "exceptions.hpp"
30 #include "copy_functors.hpp"
37 ////////////////////////////////////////////////////////////////////////////////
40 template<typename T
> class smart_ptr_holder
;
42 ////////////////////////////////////////////////////////////////////////////////
44 ////////////////////////////////////////////////////////////////////////////////
46 template<typename T
, typename C
>
50 //////////////////////////////////////////////////////////////////////////////
51 // member type definitions
55 typedef const T
& const_reference
;
58 //////////////////////////////////////////////////////////////////////////////
59 // constructors and destructors
61 // create a null pointer
64 // create a pointer containing a dynamically created object
65 // Note: the object must be allocated *by the user* with new
66 // constructor form - must be called in the form smart_ptr_base<type> x(new type(args))
67 explicit smart_ptr_base(T
* data
);
69 // copy constructor implements aliasing so no copy is made
70 // note that the copy constructor should NOT be explicit, as this breaks
71 // the returning of pointer objects from functions (at least within GCC 4.4)
72 smart_ptr_base(const smart_ptr_base
<T
,C
>& r
);
74 // assignment operator - required, else the output of GCC suffers segmentation faults
75 smart_ptr_base
<T
,C
>& operator=(const smart_ptr_base
<T
,C
>& r
);
77 // destructor decrements the reference count and delete only when the last reference is destroyed
78 ~smart_ptr_base(void);
80 //////////////////////////////////////////////////////////////////////////////
81 // logical tests to see if there is anything contained in the pointer since it can be null
83 // there are two forms:explicit and implicit
84 // implicit: if(!r) or if(r)
85 // explicit: if(r.null()) or if(r.present())
86 operator bool(void) const;
87 bool operator!(void) const;
88 bool present(void) const;
89 bool null(void) const;
91 //////////////////////////////////////////////////////////////////////////////
92 // dereference operators and functions
94 // dereference the smart pointer to get the object - use in the form *p1
95 T
& operator*(void) throw(null_dereference
);
96 const T
& operator*(void) const throw(null_dereference
);
98 // used as a prefix to a member access to the contained object e.g. p1->print() calls T::print()
99 T
* operator->(void) throw(null_dereference
);
100 const T
* operator->(void) const throw(null_dereference
);
102 //////////////////////////////////////////////////////////////////////////////
103 // explicit function forms of the above assignment and dereference operators
106 T
& value(void) throw(null_dereference
);
107 const T
& value(void) const throw(null_dereference
);
110 // deletes the previous pointer and adopts the passed pointer instead
111 // Note: the object must be allocated *by the user* with new
112 // Warning: it is very easy to break the memory management with this operation
113 void set(T
* data
= 0);
116 const T
* pointer(void) const;
118 //////////////////////////////////////////////////////////////////////////////
119 // functions to manage aliases
121 // make this an alias of the passed object
122 void alias(const smart_ptr_base
<T
,C
>&);
124 // test whether two pointers point to the same object(known as aliasing the object)
125 // used in the form if(a.aliases(b))
126 bool aliases(const smart_ptr_base
<T
,C
>&) const;
128 // find the number of aliases - used when you need to know whether an
129 // object is still referred to from elsewhere (rare!)
130 unsigned alias_count(void) const;
132 // delete the object and make the pointer null - does not make it unique
133 // first, so all other pointers to this will be null too
136 // make the pointer unique and null in one step - does not affect other
137 // pointers that were pointing to the same object
138 void clear_unique(void);
140 //////////////////////////////////////////////////////////////////////////////
141 // functions that involve copying
143 // these functions use the copy functor passed as the template parameter C
144 // to copy the object with the right copy semantics. If the copy functor
145 // is no_copy, an exception will be thrown.
147 // create a pointer containing a *copy* of the object using the template parameter C
148 // this copy is taken because the pointer class maintains a dynamically allocated object
149 // and the T& may not be (usually is not) dynamically allocated
150 explicit smart_ptr_base(const T
& data
) throw(illegal_copy
);
152 // set the value - note that this does a copy using the C template parameter
153 void set_value(const T
& data
) throw(illegal_copy
);
155 // make this pointer unique with respect to any other references to the same object
156 // if this pointer is already unique, it does nothing - otherwise it copies the object
157 void make_unique(void) throw(illegal_copy
);
159 // make this pointer a unique copy of the parameter
160 // useful for expressions like p1.copy(p2) which makes p1 a pointer to a unique copy of the contents of p2
161 void copy(const smart_ptr_base
<T
,C
>&) throw(illegal_copy
);
164 smart_ptr_holder
<T
>* m_holder
;
167 // internal use only - had to make them public because they need to be
168 // accessed by routines that could not be made friends
169 smart_ptr_holder
<T
>* _handle(void) const;
170 void _make_alias(smart_ptr_holder
<T
>* handle
);
173 ////////////////////////////////////////////////////////////////////////////////
174 // smart_ptr for simple types and classes which have copy constructors
176 template <typename T
>
177 class smart_ptr
: public smart_ptr_base
<T
, constructor_copy
<T
> >
181 explicit smart_ptr(const T
& data
) : smart_ptr_base
<T
, constructor_copy
<T
> >(data
) {}
182 explicit smart_ptr(T
* data
) : smart_ptr_base
<T
, constructor_copy
<T
> >(data
) {}
183 smart_ptr
<T
>& operator=(const T
& data
) {set_value(data
); return *this;}
184 smart_ptr
<T
>& operator=(T
* data
) {set(data
); return *this;}
188 ////////////////////////////////////////////////////////////////////////////////
189 // smart_ptr_clone for polymorphic class hierarchies which have a clone method
191 template <typename T
>
192 class smart_ptr_clone
: public smart_ptr_base
<T
, clone_copy
<T
> >
195 smart_ptr_clone(void) {}
196 explicit smart_ptr_clone(const T
& data
) : smart_ptr_base
<T
, clone_copy
<T
> >(data
) {}
197 explicit smart_ptr_clone(T
* data
) : smart_ptr_base
<T
, clone_copy
<T
> >(data
) {}
198 smart_ptr_clone
<T
>& operator=(const T
& data
) {set_value(data
); return *this;}
199 smart_ptr_clone
<T
>& operator=(T
* data
) {set(data
); return *this;}
200 ~smart_ptr_clone(void) {}
203 ////////////////////////////////////////////////////////////////////////////////
204 // smart_ptr_nocopy for any class that cannot or should not be copied
206 template <typename T
>
207 class smart_ptr_nocopy
: public smart_ptr_base
<T
, no_copy
<T
> >
210 smart_ptr_nocopy(void) {}
211 explicit smart_ptr_nocopy(T
* data
) : smart_ptr_base
<T
, no_copy
<T
> >(data
) {}
212 smart_ptr_nocopy
<T
>& operator=(T
* data
) {set(data
); return *this;}
213 ~smart_ptr_nocopy(void) {}
216 ////////////////////////////////////////////////////////////////////////////////
218 } // end namespace stlplus
220 #include "smart_ptr.tpp"
This page took 0.043869 seconds and 4 git commands to generate.