⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smart_ptr.hpp

📁 比STL和BOOST更强大的智能指针库!!! 私藏很久的老底与大家一起分享了.
💻 HPP
📖 第 1 页 / 共 5 页
字号:

/*! @struct no_checking_policy
@brief no_checking_policy has all checking functions stubbed out,
and performs no checking.
*/
struct no_checking_policy
{
	template<class T_obj> static void check_type_pass_to_constructor(T_obj*){}
	template<class T_obj> static void on_dereference(T_obj*){}
	template<class T_obj> static void on_const_dereference(T_obj*){}
	template<class T_obj> static void before_release(T_obj*){}
	template<class T_obj> static void after_release(T_obj*){}
};

// @cond INCLUDE_ALL_OBJS_
struct boost_assert_checking_policy
{
#ifdef BOOST_ASSERT
	template<class T_obj> static void check_type_pass_to_constructor(T_obj*){}
	template<class T_obj> static void on_dereference(T_obj*){}
	template<class T_obj> static void on_const_dereference(T_obj*){}
#else
	template<class T_obj> static void check_type_pass_to_constructor(T_obj* type)
	{
		BOOST_ASSERT(type != NULL);
		BOOST_ASSERT(typeid(*type) == typeid(T_obj));
	}
	template<class T_obj> static void on_dereference(T_obj* type)
	{
		BOOST_ASSERT(type != NULL);
		BOOST_ASSERT(typeid(*type) == typeid(T_obj));
	}
	template<class T_obj> static void on_const_dereference(T_obj* type)
	{
		BOOST_ASSERT(type != NULL);
		BOOST_ASSERT(typeid(*type) == typeid(T_obj));
	}
#endif //BOOST_ASSERT
	template<class T_obj> static void before_release(T_obj*){}
	template<class T_obj> static void after_release(T_obj*){}
};
// @endcond 


/*! @note
constructor_and_destructor_allocator_function is a function used
by the smart pointer that allows it to keep type information.
In a compliant C++ compiler, this function can be a static function
of the smart pointer class.  VC++ 6.0 is a prestandard compiler, 
and requires that this function be defined outside of the smart pointer
class.
*/
#if defined(_MSC_VER) && (_MSC_VER <= 1200)
template < typename TT, typename DT, typename AL> TT * constructor_and_destructor_allocator_function( TT *  ptr, bool bConstruct, DT*, AL* , void*) //Seen Note#1 below, for details on the last three arguments
{// The clone function method: (Thanks to Kai-Uwe Bux)
	if (!ptr) return NULL;
	if (bConstruct){return AL::allocate(static_cast<const DT*>(ptr));}
	AL::deallocate(ptr);
	return NULL;
}
#endif //defined(_MSC_VER) && (_MSC_VER <= 1200)


/*! @note
Note#2:\n
The following are the default policies for smart_ptr
These default policies can be replaced for a specific
translation unit, or for a specific project, by 
defining SMART_PTR_EXCLUDE_DEFAULT_POLICY_SPECIFICATIONS_
and by defining the desired policies.
To define custom default policies, do NOT use typedef.\n
Instead, use \#define.\n
If this entire package get separated into different *.hpp files, it 
than will be possible to use typedef instead of \#defines if the *.hpp
files are included in a certain order.
*/
#ifndef SMART_PTR_EXCLUDE_DEFAULT_POLICY_SPECIFICATIONS_
typedef value_comparsion_semantic_policy								comparison_default_policy;
typedef no_stream_operator_semantic_policy								stream_default_policy;
typedef no_checking_policy												checking_default_policy;
//The following two default policies are declared above the ownership polices
//typedef no_lock_policy												lock_default_policy;
//typedef ref_link_policy												ref_default_policy;
typedef copy_on_write_policy<ref_default_policy, lock_default_policy>	ownership_default_policy;
typedef no_arithmetic_semantic_policy									arithmetic_default_policy;
#endif // not SMART_PTR_EXCLUDE_DEFAULT_POLICY_SPECIFICATIONS_

/*! 
@brief smart_ptr_base is the base class for smart_ptr.
The main purpose for the smart_ptr_base is to make smart_ptr exception
safe.  When an exception is thrown, only objects that have been constructed
gets their destructor's called.  A base class gets constructed before
the derived class members.  If the base class gets constructed, and 
a the derived class member throws an exception, the base class destructor
is guaranteed to be called.
If no exception is thrown, than the base class destructor does nothing, 
because smart_ptr will nullify the pointer in it's destructor.
This insures that a memory leak does not occur if smart_ptr's members
throw an exception in their constructor.
*/
template<class T, class ALLOCATOR_POLICY>
class smart_ptr_base
{
protected:
	typedef T * ( *clone_fct_Type ) (const T *, bool, void*, ALLOCATOR_POLICY*, void*);//Last two values are not used (See note#1 at end of file)
	T* m_type;
	clone_fct_Type m_clone_fct;
	inline smart_ptr_base(T* type, clone_fct_Type clone_fct): m_type(type), m_clone_fct(clone_fct){}
	inline ~smart_ptr_base() throw()
	{
		if (m_type) m_clone_fct(m_type, false, NULL, NULL, NULL);
	}
private:
	smart_ptr_base(const smart_ptr_base&);
	smart_ptr_base& operator=(const smart_ptr_base& Src);
};


/*! @class smart_ptr
@brief 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.
@section 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.
\n
@section  Why_Use_smart_ptr 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.\n\n
For more information about why you should
prefer using smart_ptr over the boost::shared_ptr and boost pointer 
containers, see following section \ref subsection_note_prefer1
\n
@section  example_usage Example Usage
@include ../examples/example_smart_ptr_usage.cpp
\n
@section  Policy_Classes 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.
\n
@subsection subsection1 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\n
deep_copy_policy						--	Clone ownership logic, that always performance a deep copy to the pointee in the copy constructor\n
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\n
@subsubsection subsubsection1 Sub-Policy
ref_link_policy,  ref_count_policy, and ref_intrusive_policy are sub-policies of copy_on_write_policy and shared_ptr_policy\n
ref_link_policy					--	Faster than refence counting logic, but uses more memory\n
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\n
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\n
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.\n
This additional function is required to make the policy usable by both shared_ptr_policy and copy_on_write_policy\n
For reference-link VS reference-count VS reference-intrusive logic comparison, see following related link:\n
http://www.boost.org/libs/smart_ptr/smarttests.htm \n
For more information on ownership policies, read following link:\n
http://www.awprofessional.com/articles/article.asp?p=31529&seqNum=5&rl=1 \n
http://stlplus.sourceforge.net/stlplus/docs/smart_ptr.html \n

@subsection subsection2 ALLOCATOR_POLICY
The allocator policy class can be use to perform unique allocation/deallocation logic like COM or file-mapping memory.\n
However, here it's also used to link a policy with different types of clone methods.\n
Main allocator policy:\n
allocator_default_policy				--	Uses the type that is passed to the smart_ptr constructor, in order to clone the object\n
clone_function_allocator_policy			--	Uses a virtual do_clone() function in order to clone the object\n
clone_static_function_allocator_policy	--	Uses a static clone() function in order to clone the object\n
\n
<b>The following semantic policies allows the smart pointer to transfer operator logic to the pointee.</b>\n
\n
@subsection subsection3 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\n
pointer_comparsion_semantic_policy		--	Uses normal pointer semantics, which is used by most smart pointers like auto_ptr and boost::shared_ptr\n
no_comparsion_semantic_policy			--	This will make sure that a compile error is produce when trying to perform a comparison with a smart pointer\n
\n
@subsection subsection4 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\n
no_stream_operator_semantic_policy		--	Will make sure that a compile error is produced when trying to use stream operators with the smart pointer\n
\n
@subsection subsection5 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";]\n
no_arithmetic_semantic_policy			--	Will make sure that a compile error is produced when trying to use with arithmetic operators\n
\n
\verbatim
The arithmetic policy will not compile on VC++ 6.0, and it's excluded via #ifdef
\endverbatim 
@subsection SmartPtrLicense License
Copyright (C) 2005-2005 by David Maisonave (Axter)
This software library is free.\n
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.
@subsection subsection_note_prefer1 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.\n
For greater efficiency and more flexibility, it's better to use smart_ptr,
than to use boost::shared_ptr.

@section smart_ptr_Members smart_ptr Members
*/


//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
//Start of smart_ptr class

template<class T, 
	//Available OWNERSHIP_POLICY policies:				shared_ptr_policy<ref_link_policy>, copy_on_write_policy<ref_link_policy>, deep_copy_policy, shared_ptr_policy<ref_count_policy>, copy_on_write_policy<ref_count_policy>, shared_ptr_policy<ref_intrusive_policy>, copy_on_write_policy<ref_intrusive_policy>
	class OWNERSHIP_POLICY = ownership_default_policy , 
	//Available ALLOCATOR_POLICY policies:				allocator_default_policy, clone_function_allocator_policy, clone_static_function_allocator_policy
	class ALLOCATOR_POLICY =  allocator_default_policy,
	//Available CHECKING_POLICY policies:				no_checking_policy, boost_assert_checking_policy
	class CHECKING_POLICY =  checking_default_policy,
	//Available COMPARISON_SEMANTIC_POLICY policies:	value_comparsion_semantic_policy, pointer_comparsion_semantic_policy, no_comparsion_semantic_policy 
	class COMPARISON_SEMANTIC_POLICY = comparison_default_policy,
	//Available STREAM_OP_SEMANTIC_POLICY policies:		value_stream_operator_semantic_policy, no_stream_operator_semantic_policy  (Not supported on VC++6.0)
	class STREAM_OP_SEMANTIC_POLICY = stream_default_policy,
	//Available ARITHMETIC_SEMANTIC_POLICY policies:	no_arithmetic_semantic_policy, value_arithmetic_semantic_policy  (Not support for non-compliant compilers like VC++6.0 and BCC55)
	class ARITHMETIC_SEMANTIC_POLICY = arithmetic_default_policy>
class smart_ptr : smart_ptr_base<T, ALLOCATOR_POLICY>
{
	enum implement_default_object{eYes, eNo};
	mutable OWNERSHIP_POLICY m_ownership_policy;
public:
	/*! @name Constructors and Destructor */
	//@{
	/*! @brief Normal constructor which takes a valid pointer.
		smart_ptr will only clone the type that is pass to the constructor.
	*/
	template<typename T_obj>
		inline smart_ptr(T_obj* type):smart_ptr_base<T,ALLOCATOR_POLICY>(type, get_alloc_func(type))
	{
		CHECKING_POLICY::check_type_pass_to_constructor(type);
	}
	/*! @brief Copy constructor */
	inline smart_ptr(const smart_ptr& Src):smart_ptr_base<T,ALLOCATOR_POLICY>(Src.m_ownership_policy.constructor_lock_policy(Src.m_type), Src.m_clone_fct), m_ownership_policy(Src.m_ownership_policy, Src.m_type, Src.m_clone_fct, m_type){Src.m_ownership_policy.constructor_unlock_policy(Src.m_type);}
	/*! @brief Default constructor needed for std::map */
	smart_ptr(implement_default_object use_default_obj = eYes):smart_ptr_base<T,ALLOCATOR_POLICY>(NULL, NULL)
	{
		if (use_default_obj == eYes)
		{
			smart_ptr& default_obj = get_or_set_default_object();
			default_obj.lock();
			m_ownership_policy.assign(m_type, m_clone_fct, default_obj.m_type, default_obj.m_clone_fct, default_obj.m_ownership_policy, m_ownership_policy);
			default_obj.unlock();
		}
	}
	/*! @brief  Destructor */
	inline ~smart_ptr() throw()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -