SmartPointers

From user's Wiki!
Jump to: navigation, search

In this document, smart pointer and different implementations of these will be explained.


Definition

Smart pointers are objects which store pointers to dynamically allocated (heap) objects.

SmartPtr<Widget> sp(new Widget);
sp->Fun();

They behave much like built-in C++ pointers except that they automatically delete the object pointed to at the appropriate time. Smart pointers are particularly useful in the face of exceptions as they ensure proper destruction of dynamically allocated objects. They can also be used to keep track of dynamically allocated objects shared by multiple owners.

Conceptually, smart pointers are seen as owning the object pointed to, and thus responsible for deletion of the object when it is no longer needed.


Assignment strategy

Here are some possible strategies for handling the statement q = p, where p and q are smart pointers:

  1. Create a new copy of the object pointed by p, and have q point to this copy.
  2. Ownership transfer : Let both p and q point to the same object, but transfer the responsibility for cleaning up ("ownership") from p to q.
  3. Reference counting : Maintain a count of the smart pointers that point to the same object, and delete the object when this count becomes zero. So the statement q = p causes the count of the object pointed by p to increase by one.
  4. Reference linking : The same as reference counting, only instead of a count, maintain a circular doubly linked list of all smart pointers that point to the same object.
  5. Copy on write : Use reference counting or linking as long as the pointed object is not modified. When it is about to be modified, copy it and modify the copy.

Reference counting

Generally speaking, there are two ways to implement reference counting:

  1. Intrusive means that the pointed object itself contains the count. Therefore, you cannot use intrusive reference counting with 3-rd party classes that do not already have this feature. You can, however, derive a new class from the 3-rd party class and add the count to it.
  2. Non-intrusive reference counting requires an allocation of a count for each counted object.

With Intrusive reference counting, you can pass a built-in C++ pointers to another function and the reference counting will work correctly because the counter is inside the object class.

However, with non-intrusive reference counting, you cannot pass a built-in C++ pointers to a function because the counter is managed by the smart pointer class.

For example:


bool Function( Widget *w );

itk::SmartPointer<Widget> isp(new Widget);
Function( isp.GetPointer() ); // Reference counting inside the function is valid

boost::shared_ptr<Widget> nisp(new Widget);
Function( nisp.get() );	// Reference counting inside the function will be lost!!!


Implementations

Implementation Assignment strategy Observations
boost::shared_ptr Non-intrusive reference counting
boost::intrusive_ptr Intrusive reference counting The client must implement the functions
    void intrusive_ptr_add_ref(T * p);
    void intrusive_ptr_release(T * p);
  
itk::SmartPointer Intrusive reference counting
vtkObjectBase Intrusive reference counting ONLY performs reference counting. There's no smart pointer by default. However you can vtkSmartPointer
blSmartPointer Intrusive reference counting Copy of itk::SmartPointer


Note Note:
If you use VTK compiled in static mode and a library compiled in dynamic mode that uses a VTK as a parameter of a public function, there's a problem. The VTK objects are managed by factories that are static objects. You need to call DeepCopy( ).


Appendix

  1. http://www.boost.org/libs/smart_ptr/smart_ptr.htm
  2. http://www2.roguewave.com/support/docs/sourcepro/edition9-update1/html/stdlibref/auto-ptr.html
  3. http://ootips.org/yonat/4dev/smart-pointers.html