aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
gum::RefPtr< Val > Class Template Reference

Smart pointersaGrUM's smart pointers keep track of the number of times the value they point to is referenced. More...

#include <agrum/tools/core/refPtr.h>

Public Member Functions

template<typename DownVal >
INLINE RefPtr (const RefPtr< DownVal > &from)
 
template<typename DownVal >
INLINE RefPtr< Val > & operator= (const RefPtr< DownVal > &from)
 
Constructors / Destructors
 RefPtr (Val *val=0)
 Default constructor. More...
 
 RefPtr (const RefPtr< Val > &from)
 Copy constructor. More...
 
template<typename DownVal >
 RefPtr (const RefPtr< DownVal > &from)
 Copy constructor for downcastable pointers. More...
 
 ~RefPtr ()
 Class destructor. More...
 
Accessors / Modifiers
 operator bool () const
 Checks whether a RefPtr points toward something. More...
 
void clear ()
 Makes the smart pointer point to 0. More...
 
unsigned int refCount () const
 Returns the number of smart pointer referencing the contained pointer. More...
 
Operators
RefPtr< Val > & operator= (const RefPtr< Val > &from)
 Copy operator. More...
 
RefPtr< Val > & operator= (Val *from)
 Copy operator. More...
 
template<typename DownVal >
RefPtr< Val > & operator= (const RefPtr< DownVal > &from)
 Copy operator for downcastable pointers. More...
 
bool operator== (const RefPtr< Val > &from) const
 Checks whether two RefPtr<Val> are smart pointers for the same element. More...
 
bool operator!= (const RefPtr< Val > &from) const
 Checks whether two RefPtr<Val> are smart pointers for different elements. More...
 
Val * operator-> () const
 Dereferencing operator. More...
 
Val & operator* ()
 Dereferencing operator. More...
 
const Val & operator* () const
 Const dereferencing operator. More...
 

Friends

void swap (RefPtr< Val > &, RefPtr< Val > &)
 The swap function must access to gum::RefPtr private parts. More...
 

Internals

template<typename T >
class RefPtr
 A friend to allow downcastings. More...
 
template<typename T >
class HashFunc
 A friend for hashing quickly ref pointers. More...
 
Val * _val_
 The dumb pointer encapsulated into the "smart" pointer. More...
 
unsigned int * _refcount_
 A reference counter on *val. More...
 
void _destroy_ (unsigned int *, Val *)
 A function to remove the content of the smart pointer, if any. More...
 
unsigned int * _refCountPtr_ () const
 A function to return the refcount pointer. More...
 

Detailed Description

template<typename Val>
class gum::RefPtr< Val >

Smart pointers

aGrUM's smart pointers keep track of the number of times the value they point to is referenced.

When all smart pointers on a given value have been deleted, the value itself is also deleted. Thus, using RefPtr, you do not have to worry anymore about memory leaks. Note however that smart pointers impose some constraints on the way you program. Here are some rules of thumb: when several smart pointers must point to the same value, use only once the constructor taking in argument *val, and use the copy constructor or the assignment operator for the other smart pointers, else all the smart pointers will think they point to different values and thus they will all try to deallocate the dumb pointer they encapsulate, hence resulting in segmentation faults. In fact, the correct way to use the *val constructor is writing things like

RefPtr ( new myObject )

In particular, never deallocate yourself a dumb pointer you have encapsulated into a smart pointer.

Usage example:
// creation of smart pointer
RefPtr<int> ptr1 (new int (4));
// copying (and sharing) this pointer into new smart pointers
RefPtr<int> ptr2 = ptr1, ptr3;
ptr3 = ptr1;
// make ptr2 point toward nothing (this does not deallocate int (4) as it
// is pointed to by ptr1 and ptr3)
ptr2.clear ();
// modifying the value pointed to by the dumb pointer contained in ptr1
*ptr1 = 5;
// print the content of ptr3
cerr << *ptr3 << " = 5" << endl;
// check whether ptr1 and ptr3 reference the same dumb pointer
if (ptr1 == ptr2) cerr << "reference the same dumb pointer" << endl;
// check whether ptr1 and ptr2 contain a dumb pointer
if (ptr1 && !ptr2) cerr << "check containers" << endl;
Template Parameters
ValThe type referenced by the gum::RefPtr.

Definition at line 116 of file refPtr.h.

Constructor & Destructor Documentation

◆ RefPtr() [1/4]

template<typename Val >
INLINE gum::RefPtr< Val >::RefPtr ( Val *  val = 0)
explicit

Default constructor.

This constructor creates an object encapsulating the pointer passed in argument. No copy of the value pointed to by the pointer is performed. The RefPtr assumes that the value pointed to has been allocated on the heap using the new operator. If this is not the case, then using RefPtr will result in an undefined behavior when the RefPtr is destroyed (ok, we all know what it means: a segmentation fault). To avoid deleting several times the pointer encapsulated, the safe way to use the RefPtr is certainly through calls like:

RefPtr( new myObject )

Passing an already allocated pointer to the constructor is not forbidden. However, in this case, care should be taken not to allow external functions to delete the value pointed to by val. Moreover, care should be taken not to allow creating multiple RefPtr using this constructor on the same val. This would lead to unexpected results after deletion of the first RefPtr.

Parameters
valThe dumb pointer encapsulated into the object (make sure it is allocated on the heap)
Exceptions
std::bad_allocRaised if the complete RefPtr structure cannot be set properly.

Definition at line 35 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

35  : _val_(v), _refcount_(v ? new unsigned int(1U) : 0) {
36  GUM_CONSTRUCTOR(RefPtr);
37  }
friend class RefPtr
A friend to allow downcastings.
Definition: refPtr.h:330
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
+ Here is the call graph for this function:

◆ RefPtr() [2/4]

template<typename Val >
INLINE gum::RefPtr< Val >::RefPtr ( const RefPtr< Val > &  from)

Copy constructor.

Parameters
fromthe smart pointer we wish to make a copy.

Definition at line 42 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

42  :
43  _val_(from._val_), _refcount_(from._refcount_) {
44  GUM_CONS_CPY(RefPtr);
45 
46  if (_refcount_) ++*_refcount_;
47  }
friend class RefPtr
A friend to allow downcastings.
Definition: refPtr.h:330
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
+ Here is the call graph for this function:

◆ RefPtr() [3/4]

template<typename Val >
template<typename DownVal >
gum::RefPtr< Val >::RefPtr ( const RefPtr< DownVal > &  from)

Copy constructor for downcastable pointers.

Parameters
fromthe smart pointer we wish to make a copy.
Template Parameters
DownValThe downcastable type.

◆ ~RefPtr()

template<typename Val >
INLINE gum::RefPtr< Val >::~RefPtr ( )

Class destructor.

Decrements the ref count and deletes if necessary the dumb pointer.

Definition at line 165 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

165  {
166  GUM_DESTRUCTOR(RefPtr);
168  }
friend class RefPtr
A friend to allow downcastings.
Definition: refPtr.h:330
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
void _destroy_(unsigned int *, Val *)
A function to remove the content of the smart pointer, if any.
Definition: refPtr_tpl.h:63
+ Here is the call graph for this function:

◆ RefPtr() [4/4]

template<typename Val >
template<typename DownVal >
INLINE gum::RefPtr< Val >::RefPtr ( const RefPtr< DownVal > &  from)

Definition at line 53 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

53  :
54  _val_(from._val_), _refcount_(from._refcount_) {
55  GUM_CONS_CPY(RefPtr);
56 
57  if (_refcount_) ++*_refcount_;
58  }
friend class RefPtr
A friend to allow downcastings.
Definition: refPtr.h:330
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
+ Here is the call graph for this function:

Member Function Documentation

◆ _destroy_()

template<typename Val >
INLINE void gum::RefPtr< Val >::_destroy_ ( unsigned int *  count,
Val *  v 
)
private

A function to remove the content of the smart pointer, if any.

Definition at line 63 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

63  {
64  if (count) {
65  if (*count == 1U) {
66  // do not change the order of the deletes (this prevents memory leaks
67  // when
68  // the delete of v fails (note that this should probably never happen))
69  delete count;
70  delete v;
71  } else
72  --*count;
73  }
74  }
+ Here is the call graph for this function:

◆ _refCountPtr_()

template<typename Val >
INLINE unsigned int * gum::RefPtr< Val >::_refCountPtr_ ( ) const
private

A function to return the refcount pointer.

Definition at line 244 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

244  {
245  return _refcount_;
246  }
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
+ Here is the call graph for this function:

◆ clear()

template<typename Val >
INLINE void gum::RefPtr< Val >::clear ( )

Makes the smart pointer point to 0.

If necessary, the dumb pointer previously pointed to by the RefPtr is deallocated. In this case, an exception may be thrown by the destructor of the object pointed to. But, even in this case, the RefPtr guarrantees that after the completion of this method, the RefPtr will point toward 0.

Definition at line 221 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

221  {
222  // keep track of the old pointer and reference count
223  unsigned int* old_refcount = _refcount_;
224  Val* old_val = _val_;
225  // set properly the dumb pointer and its refcount
226  _val_ = 0;
227  _refcount_ = 0;
228  // now try to dereference the old dumb pointer
229  _destroy_(old_refcount, old_val);
230  }
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
void _destroy_(unsigned int *, Val *)
A function to remove the content of the smart pointer, if any.
Definition: refPtr_tpl.h:63
+ Here is the call graph for this function:

◆ operator bool()

template<typename Val >
INLINE gum::RefPtr< Val >::operator bool ( ) const

Checks whether a RefPtr points toward something.

This method enables writing code like if (refptr) perform_operation()

Definition at line 214 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

214  {
215  return (_val_ != 0);
216  }
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
+ Here is the call graph for this function:

◆ operator!=()

template<typename Val >
INLINE bool gum::RefPtr< Val >::operator!= ( const RefPtr< Val > &  from) const

Checks whether two RefPtr<Val> are smart pointers for different elements.

Returns true if either the dumb pointers the smart pointers encapsulate are different or the reference counters are different (i.e., the smart pointers are not related through copy operators).

Parameters
fromThe gum::RefPtr to test for inequality.
Returns
Returns true if this and from differ.

Definition at line 180 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

180  {
181  return from._refcount_ != _refcount_;
182  }
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
+ Here is the call graph for this function:

◆ operator*() [1/2]

template<typename Val >
INLINE Val & gum::RefPtr< Val >::operator* ( )

Dereferencing operator.

This operator is provided for convenience but you should prefer using operator -> as this is the syntax you would use with the dumb pointer. Note however that it might be useful for built-in types such as int.

Returns
Returns a reference over the value referenced by this gum::RefPtr.
Exceptions
NullElementRaised whenever the RefPtr points to 0.

Definition at line 187 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

187  {
188  if (!_val_) { GUM_ERROR(NullElement, "dereferencing a nullptr pointer") }
189 
190  return *_val_;
191  }
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ operator*() [2/2]

template<typename Val >
INLINE const Val & gum::RefPtr< Val >::operator* ( ) const

Const dereferencing operator.

This operator is provided for convenience but you should prefer using operator -> as this is the syntax you would use with the dumb pointer. Note however that it might be useful for built-in types such as int.

Returns
Returns a constant reference over the value referenced by this gum::RefPtr.
Exceptions
NullElementRaised whenever the RefPtr points to 0.

Definition at line 196 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

196  {
197  if (!_val_) { GUM_ERROR(NullElement, "dereferencing a nullptr pointer") }
198 
199  return *_val_;
200  }
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ operator->()

template<typename Val >
INLINE Val * gum::RefPtr< Val >::operator-> ( ) const

Dereferencing operator.

This operator allows developers to write code like refptr->member().

Returns
Returns a pointer over the value referenced by this gum::RefPtr.
Exceptions
NullElementRaised whenever the smart pointer points toward 0.

Definition at line 205 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

205  {
206  if (!_val_) { GUM_ERROR(NullElement, "dereferencing a nullptr pointer") }
207 
208  return _val_;
209  }
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
#define GUM_ERROR(type, msg)
Definition: exceptions.h:51
+ Here is the call graph for this function:

◆ operator=() [1/4]

template<typename Val >
template<typename DownVal >
INLINE RefPtr< Val >& gum::RefPtr< Val >::operator= ( const RefPtr< DownVal > &  from)

Definition at line 144 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

144  {
145  GUM_OP_CPY(RefPtr)
146  // keep track of the current refcount and dumb pointer
147  unsigned int* old_refcount = _refcount_;
148  Val* old_val = _val_;
149 
150  // perform the copy
151  _refcount_ = from._refcount_;
152  _val_ = from._val_;
153 
154  if (_refcount_) ++*_refcount_;
155 
156  // now try to dereference the old dumb pointer
157  _destroy_(old_refcount, old_val);
158 
159  return *this;
160  }
friend class RefPtr
A friend to allow downcastings.
Definition: refPtr.h:330
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
void _destroy_(unsigned int *, Val *)
A function to remove the content of the smart pointer, if any.
Definition: refPtr_tpl.h:63
+ Here is the call graph for this function:

◆ operator=() [2/4]

template<typename Val >
INLINE RefPtr< Val > & gum::RefPtr< Val >::operator= ( const RefPtr< Val > &  from)

Copy operator.

The operator= may throw exceptions when the dumb pointer previously pointed to by the RefPtr is deallocated (that is, the destructor of the object pointed to may throw an exception). However, even when this occurs, the RefPtr guarrantees that the copy operation is correctly performed, that is, after the completion of the function, the RefPtr points to the same element as from.

Parameters
fromThe smart pointer we wish to make a copy.
Returns
Returns this gum::RefPtr.

Definition at line 79 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

79  {
80  // avoid self assignment
81  if (_val_ != from._val_) {
82  GUM_OP_CPY(RefPtr)
83 
84  // keep track of the current refcount and dumb pointer
85  unsigned int* old_refcount = _refcount_;
86  Val* old_val = _val_;
87 
88  // perform the copy
89  _refcount_ = from._refcount_;
90  _val_ = from._val_;
91 
92  if (_refcount_) ++*_refcount_;
93 
94  // now try to dereference the old dumb pointer
95  _destroy_(old_refcount, old_val);
96  }
97 
98  return *this;
99  }
friend class RefPtr
A friend to allow downcastings.
Definition: refPtr.h:330
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
void _destroy_(unsigned int *, Val *)
A function to remove the content of the smart pointer, if any.
Definition: refPtr_tpl.h:63
+ Here is the call graph for this function:

◆ operator=() [3/4]

template<typename Val >
INLINE RefPtr< Val > & gum::RefPtr< Val >::operator= ( Val *  from)

Copy operator.

The operator= may throw exceptions when the dumb pointer previously pointed to by the RefPtr is deallocated (that is, the destructor of the object pointed to may throw an exception). However, even when this occurs, the RefPtr guarrantees that its state is coherent: either it could succeed to encapsulate the dumb pointer and this one is referenced once, or even encapsulating the new pointer failed and the RefPtr points toward the 0 pointer.

Parameters
fromthe dumb pointer we wish to encapsulate.
Returns
Returns this gum::RefPtr.

Definition at line 104 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

104  {
105  // avoid self assignment
106  if (_val_ != from) {
107  GUM_OP_CPY(RefPtr);
108 
109  // keep track of the current refcount and dumb pointer
110  unsigned int* old_refcount = _refcount_;
111  Val* old_val = _val_;
112 
113  // perform the copy
114  try {
115  if (from)
116  _refcount_ = new unsigned int(1U);
117  else
118  _refcount_ = 0;
119 
120  _val_ = from;
121  } catch (std::bad_alloc&) {
122  if (*old_refcount == 1) {
123  _val_ = from;
124  delete old_val;
125  return *this;
126  }
127 
128  _refcount_ = 0;
129  _val_ = 0;
130  throw;
131  }
132 
133  // now try to dereference the old dumb pointer
134  _destroy_(old_refcount, old_val);
135  }
136 
137  return *this;
138  }
friend class RefPtr
A friend to allow downcastings.
Definition: refPtr.h:330
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
Val * _val_
The dumb pointer encapsulated into the "smart" pointer.
Definition: refPtr.h:337
void _destroy_(unsigned int *, Val *)
A function to remove the content of the smart pointer, if any.
Definition: refPtr_tpl.h:63
+ Here is the call graph for this function:

◆ operator=() [4/4]

template<typename Val >
template<typename DownVal >
RefPtr< Val >& gum::RefPtr< Val >::operator= ( const RefPtr< DownVal > &  from)

Copy operator for downcastable pointers.

The operator= may throw exceptions when the dumb pointer previously pointed to by the RefPtr is deallocated (that is, the destructor of the object pointed to may throw an exception). However, even when this occurs, the RefPtr guarrantees that the copy operation is correctly performed, that is, after the completion of the function, the RefPtr points to the same element as from.

Template Parameters
DownValThe downcastable type.
Parameters
fromthe smart pointer we wish to make a copy.
Returns
Returns this gum::RefPtr.

◆ operator==()

template<typename Val >
INLINE bool gum::RefPtr< Val >::operator== ( const RefPtr< Val > &  from) const

Checks whether two RefPtr<Val> are smart pointers for the same element.

"Pointing toward the same element" is a little ambiguous: it does not mean that the smart pointers are pointing toward the same Val instance as several RefPtr<Val> created by the constructor with *val may point toward the same val element while being unrelated (they do not share the same reference). Instead, it means that the two smart pointers share the same reference counter, i.e., that at least one of the two smarts pointers has been created using the copy operator. As a consequence both pointers point toward the same Val instance (but the converse is false).

Parameters
fromThe gum::RefPtr to test for equality.
Returns
Returns true if this and from are equal.

Definition at line 173 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

173  {
174  return from._refcount_ == _refcount_;
175  }
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
+ Here is the call graph for this function:

◆ refCount()

template<typename Val >
INLINE unsigned int gum::RefPtr< Val >::refCount ( ) const

Returns the number of smart pointer referencing the contained pointer.

Definition at line 235 of file refPtr_tpl.h.

References gum::Set< Key, Alloc >::emplace().

235  {
236  if (_refcount_ == 0) return 0;
237 
238  return *_refcount_;
239  }
unsigned int * _refcount_
A reference counter on *val.
Definition: refPtr.h:340
+ Here is the call graph for this function:

Friends And Related Function Documentation

◆ RefPtr

template<typename Val >
template<typename T >
friend class RefPtr
friend

A friend to allow downcastings.

Definition at line 330 of file refPtr.h.

◆ HashFunc

template<typename Val >
template<typename T >
friend class HashFunc
friend

A friend for hashing quickly ref pointers.

Definition at line 334 of file refPtr.h.

◆ swap

template<typename Val >
void swap ( RefPtr< Val > &  ptr1,
RefPtr< Val > &  ptr2 
)
friend

The swap function must access to gum::RefPtr private parts.

Definition at line 251 of file refPtr_tpl.h.

251  {
252  // save from's content
253  Val* tmp_val = ptr2._val_;
254  unsigned int* tmp_refcount = ptr2._refcount_;
255  // modify from's content
256  ptr2._refcount_ = ptr1._refcount_;
257  ptr2._val_ = ptr1._val_;
258  // modify this's content
259  ptr1._val_ = tmp_val;
260  ptr1._refcount_ = tmp_refcount;
261  }

Member Data Documentation

◆ _refcount_

template<typename Val >
unsigned int* gum::RefPtr< Val >::_refcount_
private

A reference counter on *val.

Definition at line 340 of file refPtr.h.

◆ _val_

template<typename Val >
Val* gum::RefPtr< Val >::_val_
private

The dumb pointer encapsulated into the "smart" pointer.

Definition at line 337 of file refPtr.h.


The documentation for this class was generated from the following files: