Smart Pointers

smart_ptr Class Template Reference

#include <smart_ptr.hpp>

Inheritance diagram for smart_ptr:

smart_ptr_base List of all members.

Detailed Description

template<class T, class OWNERSHIP_POLICY = ownership_default_policy, class ALLOCATOR_POLICY = allocator_default_policy, class CHECKING_POLICY = checking_default_policy, class COMPARISON_SEMANTIC_POLICY = comparison_default_policy, class STREAM_OP_SEMANTIC_POLICY = stream_default_policy, class ARITHMETIC_SEMANTIC_POLICY = arithmetic_default_policy>
class smart_ptr< T, OWNERSHIP_POLICY, ALLOCATOR_POLICY, CHECKING_POLICY, COMPARISON_SEMANTIC_POLICY, STREAM_OP_SEMANTIC_POLICY, ARITHMETIC_SEMANTIC_POLICY >

smart_ptr is a smart pointer policy class that can use different ownership logic and semantic polices, which allows the developer to get the best performance and/or interface for a particular requirement.

Description

The smart_ptr class can be used with STL containers to create containers of smart pointers, moreover it can be used to create a container of abstract based objects via smart_ptr. In general, smart_ptr is faster than boost::shared_ptr. When used with STL containers, the smart pointer is faster than the boost pointer containers. More importantly, the interface for an STL container of smart_ptr is a 100% compatible with STL containers, which is not the case with the boost pointer containers. smart_ptr has a policy that allows it to synchronize access to both the smart pointer and the pointee. The smart_ptr has been compiled and tested on VC++ 6.0, 7.1, 8.0, GNU 3.x, Borland 5.5, and Comeau 4.3.

Why use smart_ptr

The short answer is use smart_ptr because it's safer, faster, more generic, more STL compatible, more adaptable, and more functional. In general, it's better to use smart pointers over raw pointers, because smart pointers automatically handle memory management, and therfore reduce memory leaks. Through the policy based designed, smart_ptr can be used for unique coding requirements. However, for most generic requirements, it can be used without specifying any particular policy, because it has default policies for the most common general use case. Unlike std::auto_ptr, smart_ptr can be used with STL containers. smart_ptr can out perform other smart pointers like boost::shared_ptr and boost pointer containers.

For more information about why you should prefer using smart_ptr over the boost::shared_ptr and boost pointer containers, see following section Why prefer using smart_pr over boost::shared_ptr and boost pointer containers

Example Usage

#include <vector>
#include <list>
#include <deque>
#include <set>
#include <map>

#include "../shape_test.h"
#include "../baseclass_test.h"


#include "../smartptr/smart_ptr.hpp"  //Only required header for normal smart_ptr usage

void example_smart_ptr_usage()
{
        smart_ptr<Shape> pShape1(new Circle("blue"));
        smart_ptr<Base,  deep_copy_policy<> >  pBase1 = new Derived1;
        smart_ptr<Shape, shared_ptr_policy<ref_link_policy>,    clone_function_allocator_policy > pShape2(new Square("white"));
        smart_ptr<Base,  copy_on_write_policy<> > pBase3(new Derived2);
        smart_ptr<Shape, shared_ptr_policy<>,   clone_function_allocator_policy > pShape4(new Square("red"));
        smart_ptr<Base,  copy_on_write_policy<ref_link_policy> > pBase5(new Derived1);
        smart_ptr<Shape, shared_ptr_policy<ref_link_policy> ,           clone_static_function_allocator_policy> pShape6(new Square("black"));

        std::vector<smart_ptr<Shape> > vShape;
        std::list<smart_ptr<Shape, deep_copy_policy<> > > lstShape;
        std::deque<smart_ptr<Shape, copy_on_write_policy<ref_link_policy>, clone_static_function_allocator_policy> > dqShape;
        //The smart_ptr can also be used with sorted containers (std::map, std::set).
        //When used with sorted containers, the base class must have an operator<() function.
        std::map<int, smart_ptr<Shape> > mShape1;
        std::map<smart_ptr<Shape>, int> mShape2;
        std::set<smart_ptr<Shape> > sShape;

}

Policy Classes

The smart_ptr has six main policy class arguments, and some of the policies themselfs have subpolicies. Over 250 different types of smart pointers can be created using the included policies. The following is an overview of the main policies.

OWNERSHIP_POLICY

shared_ptr_policy<ref_???_policy> -- Similar to boost::shared_ptr, but faster than boost::shared_ptr when used with ref_link_policy or ref_intrusive_policy
deep_copy_policy -- Clone ownership logic, that always performance a deep copy to the pointee in the copy constructor
copy_on_write_policy<ref_???_policy> -- Works like boost::shared_ptr until non-constant access. When a non-constant access is performed, than it clones if it's being referenced

Sub-Policy

ref_link_policy, ref_count_policy, and ref_intrusive_policy are sub-policies of copy_on_write_policy and shared_ptr_policy
ref_link_policy -- Faster than refence counting logic, but uses more memory
ref_count_policy -- Similar logic used by boost::shared_ptr. It uses less memory than ref_link_policy, but in (general) slower than ref_link_policy
ref_intrusive_policy -- Faster than ref_link_policy & ref_count_policy, and requires less memory. However requires implementation for intrusive_ptr_is_ref, intrusive_ptr_add_ref, intrusive_ptr_release
Note: Although ref_intrusive_policy requires the same two functions as does boost::intrusive_ptr, it has an additional requirement for a intrusive_ptr_is_ref function.
This additional function is required to make the policy usable by both shared_ptr_policy and copy_on_write_policy
For reference-link VS reference-count VS reference-intrusive logic comparison, see following related link:
http://www.boost.org/libs/smart_ptr/smarttests.htm
For more information on ownership policies, read following link:
http://www.awprofessional.com/articles/article.asp?p=31529&seqNum=5&rl=1
http://stlplus.sourceforge.net/stlplus/docs/smart_ptr.html

ALLOCATOR_POLICY

The allocator policy class can be use to perform unique allocation/deallocation logic like COM or file-mapping memory.
However, here it's also used to link a policy with different types of clone methods.
Main allocator policy:
allocator_default_policy -- Uses the type that is passed to the smart_ptr constructor, in order to clone the object
clone_function_allocator_policy -- Uses a virtual do_clone() function in order to clone the object
clone_static_function_allocator_policy -- Uses a static clone() function in order to clone the object

The following semantic policies allows the smart pointer to transfer operator logic to the pointee.

COMPARISON_SEMANTIC_POLICY:

value_comparsion_semantic_policy -- Uses value semantics instead of normal pointer semantics. This allows the smart pointer to be used with std::map and std::set
pointer_comparsion_semantic_policy -- Uses normal pointer semantics, which is used by most smart pointers like auto_ptr and boost::shared_ptr
no_comparsion_semantic_policy -- This will make sure that a compile error is produce when trying to perform a comparison with a smart pointer

STREAM_OP_SEMANTIC_POLICY:

value_stream_operator_semantic_policy -- Allows operator<< and operator>> to be used on the smart pointer, and it will transfer the logic to the pointee
no_stream_operator_semantic_policy -- Will make sure that a compile error is produced when trying to use stream operators with the smart pointer

ARITHMETIC_SEMANTIC_POLICY:

value_arithmetic_semantic_policy -- Uses value semantics instead of normal pointer semantics. This allows a type like smart_ptr<string> to work with [pString += "Hello World";]
no_arithmetic_semantic_policy -- Will make sure that a compile error is produced when trying to use with arithmetic operators

The arithmetic policy will not compile on VC++ 6.0, and it's excluded via #ifdef

License

Copyright (C) 2005-2005 by David Maisonave (Axter) This software library is free.
Permission to use, copy, modify, distribute this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies. David Maisonave (Axter) makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.

Why prefer using smart_pr over boost::shared_ptr and boost pointer containers

For those who are not familiar with the boost library, the Boost library is a well known and highly reputable portable FREE library. For more information about Boost, see following link: http://boost.org There is no existing class in the boost library that offers the same features available through smart_ptr class. However, smart_ptr can be compared to the boost::shared_ptr and the boost pointer containers, because it can replace their usage. In general, smart_ptr is faster than boost::shared_ptr, because by default, smart_ptr uses reference linking instead of reference counting. A container of smart_ptr has a better STL compatible interface than does the boost pointer containers, and unlike the boost pointer containers, a container of smart_ptr will compile with no compile warnings on VC++ 7.1 & 8.0. Also, unlike boost pointer containers, the smart_ptr can compile on VC++ 6.0. The smart_ptr class also has better methods to avoid splicing than does the boost pointer containers, and it allows for more generic development, by not forcing the target pointee to have cloning functions. An STL container of smart_ptr is copiable. The boost pointer containers have no copy constructors, so they're not copiable vai copy constructor. The logic required to copy a boost pointer container performs poorly compared to using the copy constructor of an STL container of smart_ptr. The boost pointer containers have many incompatibility issues with the STL containers. These incompatibility issues do not exist in a container of smart_ptr.

To have greater compatibility and efficiency, it's better to use an STL container of smart_ptr than to use the boost pointer containers.
For greater efficiency and more flexibility, it's better to use smart_ptr, than to use boost::shared_ptr.

smart_ptr Members

Definition at line 1159 of file smart_ptr.hpp.

Constructors and Destructor

template<typename T_obj>
 smart_ptr (T_obj *type)
 Normal constructor which takes a valid pointer. smart_ptr will only clone the type that is pass to the constructor.
 smart_ptr (const smart_ptr &Src)
 Copy constructor.
 smart_ptr (implement_default_object use_default_obj=eYes)
 Default constructor needed for std::map.
 ~smart_ptr () throw ()
 Destructor.
template<class CompatibleDerivedT, class OWNERSHIP_POLICY_T, class ALLOCATOR_POLICY_T, class CHECKING_POLICY_T, class COMPARISON_SEMANTIC_POLICY_T, class STREAM_OPERATOR_SEMANTIC_POLICY_T, class ARITHMETIC_SEMANTIC_POLICY_T>
 smart_ptr (const smart_ptr< CompatibleDerivedT, OWNERSHIP_POLICY_T, ALLOCATOR_POLICY_T, CHECKING_POLICY_T, COMPARISON_SEMANTIC_POLICY_T, STREAM_OPERATOR_SEMANTIC_POLICY_T, ARITHMETIC_SEMANTIC_POLICY_T > &Src)
 Constructor for smart pointer derived type smart_ptr<DerivedT>.

Operators

template<class CompatibleDerivedT, class OWNERSHIP_POLICY_T, class ALLOCATOR_POLICY_T, class CHECKING_POLICY_T, class COMPARISON_SEMANTIC_POLICY_T, class STREAM_OPERATOR_SEMANTIC_POLICY_T, class ARITHMETIC_SEMANTIC_POLICY_T>
smart_ptroperator= (const smart_ptr< CompatibleDerivedT, OWNERSHIP_POLICY_T, ALLOCATOR_POLICY_T, CHECKING_POLICY_T, COMPARISON_SEMANTIC_POLICY_T, STREAM_OPERATOR_SEMANTIC_POLICY_T, ARITHMETIC_SEMANTIC_POLICY_T > &Src)
smart_ptroperator= (smart_ptr &Src)
 Assignment operator.
bool operator! () const
arith_retrn_type & operator+= (const smart_ptr &Src)
template<class T2>
arith_retrn_type & operator+= (const T2 &Src)
arith_retrn_type & operator-= (const smart_ptr &Src)
template<class T2>
arith_retrn_type & operator-= (const T2 &Src)
ownership_retrn_type_pointee operator-> ()
ownership_retrn_type_ref operator * ()
ownership_retrn_type_pointee operator-> () const
ownership_retrn_type_ref operator * () const
arith_retrn_type operator+ (const smart_ptr &a, const smart_ptr &b)
arith_retrn_type operator- (const smart_ptr &a, const smart_ptr &b)

Synchronize Methods

void lock () const
 lock function is used with lock policy, and can be called manually (directly), or automatically through scope_lock.
void unlock () const
 unlock function is used with lock policy, and can be called manually (directly), or automatically through scope_lock.
void trylock () const
 trylock is an optional synchronization function that can be used with the lock policy. Use islock function to test trylock success. Some implementations do not support trylock and islock logic.
void islock () const
 islock is an optional synchronization function that can be used with the lock policy. The islock function should never be used with lock() method, and should only be used with trylock(). Some implementations do not support trylock and islock logic.

Misc Methods

template<class T2>
smart_ptrequal (const T2 &Src)
 Use equal method to test if two pointee's are equal to each other. This does not test if the address of the pointers are equal to each other, and instead test if what the pointers are pointing to, are equal to each other.
clone_fct_Type get_function_ptr () const
 The get_function_ptr method is mainly for internal usage, but it can not be made private/protected because policy methods require access to this method.
void swap (smart_ptr< T > &other) throw ()
 The swap method is not used by any policy, and it's implemented here to make this class compatible with generic coding.
template<class PT, class FPT>
void make_clone (PT *&ptr, FPT &func_ptr) const
 The make_clone method is used to allow other smart pointers access to the cloning logic. One of the main reasons it's required, is because a derived T type, would not have access to the private members (m_clone_fct & m_type), so without make_clone, it would be difficult to clone smart_ptr's if the T type where not the same.
static void set_default_object (const smart_ptr &NewValue)
 For added safety, call set_default_object to set default object before using this class as the second type in a std::map container.

Common Pointer Access Methods

T * get_ptr ()
const T * c_ptr () const
const T & c_ref () const

Friends

template<class T1>
bool operator== (const smart_ptr &a, const T1 &b)
template<class T1>
bool operator!= (const smart_ptr &a, const T1 &b)
template<class T1>
bool operator> (const smart_ptr &a, const T1 &b)
template<class T1>
bool operator< (const smart_ptr &a, const T1 &b)
template<class T1>
bool operator>= (const smart_ptr &a, const T1 &b)
template<class T1>
bool operator<= (const smart_ptr &a, const T1 &b)
template<class TS>
TS & operator>> (TS &is, smart_ptr &obj)
template<class TS>
TS & operator<< (TS &io, const smart_ptr &obj)


The documentation for this class was generated from the following file:
Generated on Wed Mar 29 21:58:59 2006 for Smart Pointers by  doxygen 1.4.6.Axter [Axter-Extended-Version]