KDIS  2-8-x
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
KRef_Ptr.h
Go to the documentation of this file.
1 /*********************************************************************
2 Copyright 2013 Karl Jones
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 
8 1. Redistributions of source code must retain the above copyright notice, this
9  list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation
12  and/or other materials provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 
25 For Further Information Please Contact me at
26 Karljj1@yahoo.com
27 http://p.sf.net/kdis/UserGuide
28 *********************************************************************/
29 
30 /********************************************************************
31 class: KRef_Ptr
32 created: 2009/07/22
33 author: Karl Jones
34 
35 purpose: Implementation of a referenced smart pointer.
36  Holds a counter of how many references are currently held of a pointer.
37  When the final reference is released the memory is released.
38 
39  -*How To Use:*-
40 
41  KRef_Ptr<MyClass> pObj = new MyClass;
42 
43  pObj can now be used like a normal pointer.
44 
45  E.G
46 
47  pObj->func();
48  *pObj.func();
49 
50  -*Note:*-
51 
52  Be carefull of the following mistakes:
53 
54  - MyClass * p = pObj.GetPtr(); // p is not safe. It could be deleted when the KRef_Ptr goes out of scope leaving you with a NULL pointer.
55 
56  - KRef_Ptr<MyClass> pRef = pObj.GetPtr(); // This will create a second reference to the pointer which will cause problems.
57 
58  instead use
59 
60  KRef_Ptr<MyClass> pRef = pObj;
61 *********************************************************************/
62 
63 #pragma once
64 
65 #include "./../KDefines.h"
66 
67 namespace KDIS {
68 namespace UTILS {
69 
70 typedef KDIS::KUINT16 RefCounter; // Change the counter to KUINT32 if you expect to have over 65,535 references.
71 
72 template<class Type>
73 class KRef_Ptr
74 {
75 private:
76 
77  Type * m_pRef;
78 
79  RefCounter * m_piCount;
80 
81  //************************************
82  // FullName: KRef_Ptr<Type>::ref
83  //!Description: Increments reference counter
84  //************************************
85  void ref()
86  {
87  if( m_pRef )++( *m_piCount );
88  };
89 
90  //************************************
91  // FullName: KRef_Ptr<Type>::unRef
92  //!Description: Decrements reference counter, cleans
93  //! up if no other references exist.
94  //************************************
95  void unRef()
96  {
97  if( m_pRef )
98  {
99  --( *m_piCount );
100  if( *m_piCount == 0 )
101  {
102  delete m_piCount;
103  delete m_pRef;
104  m_piCount = NULL;
105  m_pRef = NULL;
106  }
107  }
108  };
109 
110 public:
111 
113  m_pRef( NULL ),
114  m_piCount( NULL )
115  {
116  };
117 
118  KRef_Ptr( Type * p )
119  {
120  m_pRef = p;
121  m_piCount = new RefCounter;
122  *m_piCount = 0;
123  ref();
124  };
125 
126  KRef_Ptr( const KRef_Ptr<Type> & p ) :
127  m_pRef( p.m_pRef ),
128  m_piCount( p.m_piCount )
129  {
130  ref();
131  };
132 
133  virtual ~KRef_Ptr()
134  {
135  unRef();
136  };
137 
138  //************************************
139  // FullName: KRef_Ptr<Type>::Clear
140  //!Description: Removes the current reference held.
141  //************************************
142  void Clear()
143  {
144  unRef();
145  m_pRef = NULL;
146  m_piCount = NULL;
147  };
148 
149  //************************************
150  // FullName: KRef_Ptr<Type>::GetPtr
151  //!Description: Returns pointer to the current reference
152  //! or NULL if no reference exists.
153  //! Note: The returned pointer will not be safe. Avoid using this function.
154  //************************************
155  Type * GetPtr() const
156  {
157  return m_pRef;
158  };
159 
160  //************************************
161  // FullName: KRef_Ptr<Type>::GetCount
162  //!Description: Returns number of reference that currently exist
163  //! for this pointer or 0 if no reference is held.
164  //************************************
166  {
167  if( m_piCount )return *m_piCount;
168  };
169 
170  //************************************
171  // FullName: KRef_Ptr<Type>::operator=
172  //!Description: Assignment of an other KRef_Ptr.
173  // Parameter: const KRef_Ptr<Type> & p
174  //************************************
176  {
177  if( m_pRef == p.m_pRef )return *this;
178  unRef();
179  m_pRef = p.m_pRef;
180  m_piCount = p.m_piCount;
181  ref();
182  return *this;
183  };
184 
185  //************************************
186  // FullName: KRef_Ptr<Other>::operator=
187  //!Description: Assignment of an other KRef_Ptr of a different type.
188  // Parameter: const KRef_Ptr<Other> & p
189  //************************************
190  template<class Other>
192  {
193  unRef();
194  m_pRef = p.m_pRef;
195  m_piCount = p.m_piCount;
196  ref();
197  return *this;
198  };
199 
200  //************************************
201  // FullName: KRef_Ptr<Type>::operator=
202  //!Description: Assignment of a new reference.
203  // Parameter: Type * p
204  //************************************
205  KRef_Ptr<Type> & operator=( Type * p )
206  {
207  if( m_pRef == p )return *this;
208  unRef();
209  m_pRef = p;
210  m_piCount = new RefCounter;
211  *m_piCount = 0;
212  ref();
213  return *this;
214  };
215 
216  //************************************
217  // FullName: KRef_Ptr<Other>::operator=
218  //!Description: Assignment of a new reference of a different type.
219  // Parameter: Other * p
220  //************************************
221  template<class Other>
222  KRef_Ptr<Type> & operator=( Other * p )
223  {
224  unRef();
225  m_pRef = p;
226  m_piCount = new RefCounter;
227  *m_piCount = 0;
228  ref();
229  return *this;
230  };
231 
232  //************************************
233  // FullName: KRef_Ptr<Type>::operator==
234  //!Description: Comparison equals. Checks if both references are the same.
235  // Parameter: const KRef_Ptr<Type> & p
236  //************************************
237  KBOOL operator==( const KRef_Ptr<Type> & p )const
238  {
239  return m_pRef == p.m_pRef;
240  };
241 
242  //************************************
243  // FullName: KRef_Ptr<Other>::operator==
244  //!Description: Comparison equals. Checks if both references are the same of a
245  //! different type.
246  //! E.G An upast/downcast of the current type.
247  // Parameter: const KRef_Ptr<Other> & p
248  //************************************
249  template<class Other>
250  KBOOL operator==( const KRef_Ptr<Other> & p )const
251  {
252  return m_pRef == p.m_pRef;
253  };
254 
255  //************************************
256  // FullName: KRef_Ptr<Type>::operator*
257  //!Description: When referencing the KRef_Ptr return our referenced object.
258  //************************************
259  Type & operator*() const
260  {
261  return *m_pRef;
262  };
263 
264  //************************************
265  // FullName: KRef_Ptr<Type>::operator->
266  //!Description: Returns the referenced pointer.
267  //************************************
268  Type * operator->() const
269  {
270  return m_pRef;
271  };
272 
273  //************************************
274  // FullName: KRef_Ptr<Type>::operator!=
275  //!Description: Comparison does not equals. Compares the referenced pointer to an unsafe pointer.
276  // Parameter: const Type * p
277  //************************************
278  KBOOL operator!= ( const Type * p ) const
279  {
280  return m_pRef != p;
281  };
282 
283  //************************************
284  // FullName: KRef_Ptr<Other>::operator!=
285  //!Description: Comparison does not equals. Compares the referenced pointer to an unsafe pointer of a different type.
286  //! E.G a derrived type.
287  // Parameter: const Other * p
288  //************************************
289  template<class Other>
290  KBOOL operator!= ( const Other * p ) const
291  {
292  return m_pRef != p;
293  };
294 
295  //************************************
296  // FullName: KRef_Ptr<Type>::operator!=
297  //!Description: Comparison does not equals. Compares the referenced pointer to an other KRef_Ptr.
298  // Parameter: const KRef_Ptr<Type> & p
299  //************************************
300  KBOOL operator!= ( const KRef_Ptr<Type> & p ) const
301  {
302  return m_pRef != p.m_pRef;
303  };
304 
305  //************************************
306  // FullName: KRef_Ptr<Other>::operator!=
307  //!Description: Comparison does not equals. Compares the referenced pointer to an other KRef_Ptr of a different type.
308  // Parameter: const KRef_Ptr<Other> & p
309  //************************************
310  template<class Other>
311  KBOOL operator!= ( const KRef_Ptr<Other> & p ) const
312  {
313  return m_pRef != p.m_pRef;
314  };
315 };
316 
317 
318 } // END namespace UTILS
319 } // END namespace KDIS
KBOOL operator!=(const Type *p) const
Description: Comparison does not equals. Compares the referenced pointer to an unsafe pointer...
Definition: KRef_Ptr.h:278
Type * GetPtr() const
Definition: KRef_Ptr.h:155
KRef_Ptr< Type > & operator=(const KRef_Ptr< Other > &p)
Description: Assignment of an other KRef_Ptr of a different type.
Definition: KRef_Ptr.h:191
RefCounter GetCount() const
Definition: KRef_Ptr.h:165
unsigned short int KUINT16
Definition: KDefines.h:101
KRef_Ptr< Type > & operator=(Type *p)
Description: Assignment of a new reference.
Definition: KRef_Ptr.h:205
KRef_Ptr< Type > & operator=(Other *p)
Description: Assignment of a new reference of a different type.
Definition: KRef_Ptr.h:222
virtual ~KRef_Ptr()
Definition: KRef_Ptr.h:133
KRef_Ptr< Type > & operator=(const KRef_Ptr< Type > &p)
Description: Assignment of an other KRef_Ptr.
Definition: KRef_Ptr.h:175
bool KBOOL
Definition: KDefines.h:119
Type & operator*() const
Description: When referencing the KRef_Ptr return our referenced object.
Definition: KRef_Ptr.h:259
KDIS::KUINT16 RefCounter
Definition: KRef_Ptr.h:70
KBOOL operator==(const KRef_Ptr< Type > &p) const
Description: Comparison equals. Checks if both references are the same.
Definition: KRef_Ptr.h:237
Type * operator->() const
Description: Returns the referenced pointer.
Definition: KRef_Ptr.h:268
KRef_Ptr(Type *p)
Definition: KRef_Ptr.h:118
KBOOL operator==(const KRef_Ptr< Other > &p) const
Definition: KRef_Ptr.h:250
KRef_Ptr()
Definition: KRef_Ptr.h:112
void Clear()
Description: Removes the current reference held.
Definition: KRef_Ptr.h:142
Definition: KRef_Ptr.h:73
KRef_Ptr(const KRef_Ptr< Type > &p)
Definition: KRef_Ptr.h:126