软件架构设计之Utility模块——智能指针
2013-03-18 23:01
211 查看
一:前言
大家应该明白智能指针的用途(管理动态对象的生命期)及好处。其他话就不多说了,直接看如何实现吧。你将会看到一个基于策略而实作出的无比强大,灵活的智能指针。参考的依然是《Modern C++ Design》一书。二:原理说明
软件工程比其他工程有更丰富的多样性。你可以采用多种正确的方法去完成一件事情。一旦你选择了一种解决方案,便会有一大堆变化随之涌现,大至系统架构,小至程序片段。设计的多样性不断困扰着程序员。什么是最好的解决方法?是Events,还是Observers?Callbacks?virtuals?Template?任何设计结构上的问题,都有许多合适的解法,然而他们各有不同规格,并且各有优缺点。因此我们会面临各种不同的抉择。在“一个全功能型接口下实作所有东西”来满足我们各种不同的抉择显然会是失败的。Policy有助于我们设计出安全,有效率,高度弹性且高复用性的“设计元素”。所谓Policy:定义一个小型Class或Class Template,他们只是单纯的完成某一方面的主题,在“遵循Policy接口”的前提下,你可以采用任何方法来实作Policy。接着你可以混合和匹配各种Policy,就可以完成一个“行为集”。
接下来采用此原理来实现我们的“智能指针”。实作完后大家可以认真理解Policy-base design(基于策略的设计)
三:实作
先来划分智能指针的主题(将其划分为5个):1.所管理的对象类型(T)2.拥有权策略(OwnerPolicy)3.安全检查策略(CheckPolicy)4.存储策略(StoragePolicy)5.线程策略(ThreadPolicy)。将每个主题作为HTSmartPtr的模板参数。一个主题仅涉及某一特定功能(他们提供统一的接口)。在遵循相应主题的接口下,你可以用不同的方式(Policy实现)完成该主题所需的功能。在每个主题下,你可以选择一种方式(Policy实现)来完成HTSmartPtr。没选择一种不同的Policy实现,你都会产生一种新的智能指针。因此甚至你可以说,可以产生无穷无尽的智能指针。现在的问题我的主题一开始划分不正确怎么办。Policy只是很单纯的完成某一功能,因此你完全可以把原因划在A主题的Policy实现,改换成B主题下。这不需要动大量的代码,因为我们已将HTSmartPtr与Policy实现解耦。HTSmartPtr是由Policy实现组合产生的,只不过将这些Policy实现分类。而与HTSmartPt无关。
1. 拥有权策略(OwnerPolicy)
这里我仅提供拥有权策略的三个Policy实现:引用计数,引用计数的观察者,作用域为范围。由于引用计数及观察者是配套使用的,因此一起讲:
引用计数:等同于boost中的share_ptr。采用该方案的智能指针是可以共享的。
观察者:等同于boost中的weak_ptr。采用该方案的智能指针是不允许外界访问其拥有的对象,必须转换为引用计数(此过程可以判断该对象是否还有效,有效防止类成员变量为指针类型可能出现的野指针问题)。
作用域为范围:用于局部变量,退出作用域时自动释放。不可共享。
看代码:
class HTCounter // 引用智能指针计数器 { private: HTCounter(HTCounter const & ); HTCounter& operator = (HTCounter const & ); public: HTCounter() : m_nRefCount(0), m_nWeakCount(0) {} void RefAdd() {++m_nRefCount;} bool RefRelease() {--m_nRefCount; return m_nRefCount == 0;} HT_UINT GetRefCount() { return m_nRefCount; } void WeakAdd() {++m_nWeakCount;} bool WeakRelease() {--m_nWeakCount; return m_nWeakCount == 0;} HT_UINT GetWeakCount() { return m_nWeakCount; } void Swap(HTCounter& rhs) { std::swap(m_nRefCount, rhs.m_nRefCount); std::swap(m_nWeakCount, rhs.m_nWeakCount);} private: HT_UINT m_nRefCount; // 实际引用计数值 HT_UINT m_nWeakCount; // 观察者的引用计数值 }; template <class P> class WeakCounted; template <class P> class RefCounted // 引用计数 { template <typename T> friend class WeakCounted; public: RefCounted() : m_pCount(0) {} RefCounted(const RefCounted& rhs) : m_pCount(rhs.m_pCount) {} template <typename P1> RefCounted(const WeakCounted<P1>& rhs) : m_pCount(reinterpret_cast<const WeakCounted<P1>&>(rhs).ValidCounter()) {} template <typename P1> RefCounted(const RefCounted<P1>& rhs) : m_pCount(reinterpret_cast<const RefCounted&>(rhs).m_pCount) {} void NewCount() { m_pCount = static_cast<HTCounter*>( HTMemSmall<>::operator new(sizeof(HTCounter))); assert(m_pCount); new (m_pCount)HTCounter; m_pCount->RefAdd(); } P Clone(const P& val) { if (m_pCount) m_pCount->RefAdd(); return m_pCount ? val : HT_NULL; } bool Release(const P&) { if (m_pCount && m_pCount->RefRelease()) { // 当引用计数、观察者计数均为0时释放计数器 if (!m_pCount->GetWeakCount()) { m_pCount->~HTCounter(); HTMemSmall<>::operator delete(m_pCount, sizeof(HTCounter)); m_pCount = 0; } return true; } return false; } void Swap(RefCounted& rhs) { std::swap(m_pCount, rhs.m_pCount); } private: HTCounter* m_pCount; }; template <class P> class WeakCounted // 观察者计数 { public: WeakCounted() : m_pCount(0) {} WeakCounted(const WeakCounted& rhs) : m_pCount(rhs.m_pCount) {} template <typename P1> WeakCounted(const RefCounted<P1>& rhs) : m_pCount(reinterpret_cast<const RefCounted<P1>&>(rhs).m_pCount) {} template <typename P1> WeakCounted(const WeakCounted<P1>& rhs) : m_pCount(reinterpret_cast<const WeakCounted&>(rhs).m_pCount) {} void NewCount() { assert(false); } P Clone(const P& val) { if (m_pCount) m_pCount->WeakAdd(); return val; } bool Release(const P&) { if (m_pCount && m_pCount->WeakRelease()) { // 当引用计数、观察者计数均为0时释放计数器 if (!m_pCount->GetShareCount()) { HTMemSmall<>::operator delete(m_pCount, sizeof(HTCounter)); m_pCount = 0; } } return false; } HTCounter* ValidCounter() const { // 当引用计数非0 if (m_pCount && m_pCount->GetShareCount()) return m_pCount; return HT_NULL; } void Swap(WeakCounted& rhs) { std::swap(m_pCount, rhs.m_pCount); } template <typename T> friend class RefCounted; private: HTCounter* m_pCount; }; template <class P> class OwnerScoped { public: void NewCount() {} bool Release(const P&) { return true; } };
2. 安全检查策略(CheckPolicy)
这里仅提供两种Plicy实现:CheckNo(不进行任何检查),CheckAssert(提领前进行assert检查是否为null)。CheckNo: 不提供任何检验
CheckAssert:// 提领前断言检验
template <class P> struct CheckNo { CheckNo() {} template <class P1> CheckNo(const CheckNo<P1>&) {} static void OnDefault(const P&) {} static void OnInit(const P&) {} static void OnDereference(const P&) {} static void Swap(CheckNo&) {} }; template <class P> struct CheckAssert { CheckAssert() {} template <class P1> CheckAssert(const CheckAssert<P1>&) {} template <class P1> CheckAssert(const CheckNo<P1>&) {} static void OnDefault(const P&) {} static void OnInit(const P&) {} static void OnDereference(P val) { assert(val); (void) val; } static void Swap(CheckAssert&) {} };
3. 存储策略(StoragePolicy):
这里仅提供三种Policy实现:StorageNo(不为所管理的对象分配内存),StoragePool(在内存池中分配对象),StorageNew(即使用new 分配对象,delete释放对象)。StorageNo:不含分配对象内存功能
StoragePool:在内存池中为对象分配空间,这里选用的是HTMemFlex,可参看内存分配部分
StorageNew:使用new分配,delete释放
template <typename T> class HTStorageNo { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T* stored_type; HTStorageNo() : m_pT(0) {} HTStorageNo(const HTStorageNo&) {} template <class U> HTStorageNo(const HTStorageNo<U>&);// {} // template <class U> // HTStorageNo(const YKStorageChunk<U>&) {} void Create() { assert(false); } void Destroy() { assert(false); } pointer operator-> () const { BOOST_STATIC_ASSERT(0); return m_pT;} reference operator* () const { BOOST_STATIC_ASSERT(0); return *m_pT;} void Swap(HTStorageNo& rhs) { std::swap(m_pT, rhs.m_pT); } friend inline pointer GetImpl(const HTStorageNo& sp) { return sp.m_pT; } friend inline const stored_type& GetImplRef(const HTStorageNo& sp) { return sp.m_pT; } friend inline stored_type& GetImplRef(HTStorageNo& sp) { return sp.m_pT; } private: stored_type m_pT; }; template <typename T> class HTStorageNew { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T* stored_type; void Create() { m_pT = new T(); } void Destroy() { delete m_pT; m_pT = 0; } pointer operator-> () const {return m_pT;} reference operator* () const {return *m_pT;} void Swap(HTStorageNew& rhs) {std::swap(m_pT, rhs.m_pT);} friend inline pointer GetImpl(const HTStorageNew& sp) {return sp.m_pT;} friend inline const stored_type& GetImplRef(const HTStorageNew& sp) {return sp.m_pT;} friend inline stored_type& GetImplRef(HTStorageNew& sp) {return sp.m_pT;} private: stored_type m_pT; }; template <typename T> class HTStoragePool : public HTMemFlex<T> { public: typedef T value_type; typedef T* pointer; typedef const T* const_pointer; typedef T& reference; typedef const T& const_reference; typedef T* stored_type; public: HTStoragePool() : m_pT(0) {} HTStoragePool(const HTStoragePool&) {} template <class U> HTStoragePool(const HTStoragePool<U>&) {} // template <class U> // HTStoragePool(const YKStorageNo<U>&) {} HTStoragePool(const stored_type& p) : m_pT(p) {} ~HTStoragePool() {} void Create() { m_pT = Allocate(sizeof(value_type)); } void Destroy() { Deallocate(m_pT); m_pT = 0; } pointer operator-> () const {return m_pT;} reference operator* () const {return *m_pT;} void Swap(HTStoragePool& rhs) {std::swap(m_pT, rhs.m_pT);} friend inline pointer GetImpl(const HTStoragePool& sp) {return sp.m_pT;} friend inline const stored_type& GetImplRef(const HTStoragePool& sp) {return sp.m_pT;} friend inline stored_type& GetImplRef(HTStoragePool& sp) {return sp.m_pT;} private: stored_type m_pT; };
4. 线程策略(ThreadPolicy)
两个Policy实现:ThreadSingle(单线程实现),ThreadMulti(多线程实现)ThreadSingle:不用加锁保护,用于单线程环境。
ThreadMulti:可用于多线程环境。
暂不实现该策略,等实现完线程部分再来实在该策略。
5. 将一切组装起来
默认实现一个引用计数,不进行任何检查,使用自定义内存池来分配对象的智能指针。template <typename T, template <class> class OwnerPolicy = RefCounted, template <class> class CheckPolicy = CheckNo, template <class> class StoragePolicy = HTStoragePool> class HTSmartPtr : public StoragePolicy<T> , public OwnerPolicy<typename StoragePolicy<T>::pointer> , public CheckPolicy<typename StoragePolicy<T>::stored_type> { typedef StoragePolicy<T> MP; typedef OwnerPolicy<typename StoragePolicy<T>::pointer> OP; typedef CheckPolicy<typename StoragePolicy<T>::stored_type> KP; public: typedef typename MP::reference reference; typedef typename MP::const_reference const_reference; typedef typename MP::pointer pointer; typedef typename MP::const_pointer const_pointer; typedef typename MP::value_type value_type; public: HTSmartPtr(bool bNew = false) // 需要分配对象则传true { if (bNew) { NewObj(); } } void NewObj() { assert(!ValidObj()); Create(); NewCount(); } HTSmartPtr(int rhs) // 只接受HT_NULL,不接受裸指针 { assert(rhs == HT_NULL); HTSmartPtr temp; temp.Swap(*this); } HTSmartPtr(HTSmartPtr& rhs) : MP(rhs), OP(rhs), KP(rhs) { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } template <typename T1, template <class> class OP1, template <class> class KP1, template <class> class MP1> HTSmartPtr(const HTSmartPtr<T1, OP1, KP1, MP1>& rhs) : MP(rhs), OP(rhs), KP(rhs) { GetImplRef(*this) = OP::Clone(HT_Safe_DownCast<pointer>(GetImplRef(rhs))); } template <typename T1, template <class> class OP1, template <class> class KP1, template <class> class MP1> HTSmartPtr(HTSmartPtr<T1, OP1, KP1, MP1>& rhs) : MP(rhs), OP(rhs), KP(rhs) { GetImplRef(*this) = OP::Clone(HT_Safe_DownCast<pointer>(GetImplRef(rhs))); } HTSmartPtr& operator= (HTSmartPtr& rhs) { HTSmartPtr temp(rhs); temp.Swap(*this); return *this; } HTSmartPtr& operator= (int rhs) { assert(rhs == HT_NULL); HTSmartPtr temp; temp.Swap(*this); return *this; } template <typename T1, template <class> class OP1, template <class> class KP1, template <class> class MP1> HTSmartPtr& operator= (const HTSmartPtr<T1, OP1, KP1, MP1>& rhs) { HTSmartPtr temp(rhs); temp.Swap(*this); return *this; } template <typename T1, template <class> class OP1, template <class> class KP1, template <class> class MP1> HTSmartPtr& operator= (HTSmartPtr<T1, OP1, KP1, MP1>& rhs) { HTSmartPtr temp(rhs); temp.Swap(*this); return *this; } void Swap(HTSmartPtr& rhs) { OP::Swap(rhs); KP::Swap(rhs); MP::Swap(rhs); } ~HTSmartPtr() { if (OP::Release(GetImpl(*static_cast<MP*>(this)))) { Destroy(); } } pointer operator-> () { KP::OnDereference(GetImplRef(*this)); return MP::operator ->(); } pointer operator-> () const { KP::OnDereference(GetImplRef(*this)); return MP::operator ->(); } reference operator* () { KP::OnDereference(GetImplRef(*this)); return MP::operator *(); } reference operator* () const { KP::OnDereference(GetImplRef(*this)); return MP::operator *(); } inline friend HT_BOOL operator==(const HTSmartPtr& lhs, const_pointer rhs) { return GetImpl(lhs) == rhs; } inline friend HT_BOOL operator==(const_pointer lhs, const HTSmartPtr& rhs) { return rhs == lhs; } inline friend HT_BOOL operator!=(const HTSmartPtr& lhs, const_pointer rhs) { return !(lhs == rhs); } inline friend HT_BOOL operator!=(const_pointer lhs, const HTSmartPtr& rhs) { return rhs != lhs; } template <typename T1, template <class> class OP1, template <class> class KP1, template <class> class MP1> inline HT_BOOL operator== (const HTSmartPtr<T1, OP1, KP1, MP1>& rhs) const {return *this == GetImpl(rhs);} template <typename T1, template <class> class OP1, template <class> class KP1, template <class> class MP1> inline bool operator!= (const HTSmartPtr<T1, OP1, KP1, MP1>& rhs) const {return !(*this == rhs);} template <typename T1, template <class> class OP1, template <class> class KP1, template <class> class MP1> inline bool operator< (const HTSmartPtr<T1, OP1, KP1, MP1>& rhs) const {return !(*this < rhs);} template <typename T1, template <class> class OP1, template <class> class KP1, template <class> class MP1> inline bool operator> (const HTSmartPtr<T1, OP1, KP1, MP1>& rhs) const {return !(*this > rhs);} inline pointer GetValue() { return GetImpl(*this); } inline pointer GetValue() const { return GetImpl(*this); } inline bool ValidObj() { return GetImpl(*this) != 0; } inline bool ValidObj() const { return GetImpl(*this) != 0; }
相关文章推荐
- 软件架构设计之Utility模块——内存分配
- 软件架构设计之Utility模块——DateTime
- 软件架构设计之Utility模块——string
- 软件架构设计之Utility模块——Functor
- 软件架构设计之Utility模块——string
- 软件架构设计之Utility模块——DateTime
- 软件架构设计之Utility模块——Any
- 软件架构设计之Utility模块——Any
- 【系统架构师】软件架构设计——1 软件架构概念与模型
- 数据库软件架构设计些什么
- 软件架构模式和设计模式
- 如何做好软件系统的架构设计?
- 企业管理软件开发架构之七 Object Control设计与运用
- 软件架构为谁而设计
- 谈谈对一些软件架构设计箴言的理解
- 软件架构设计的一般过程
- 软件架构设计策略
- 软件架构与设计[Software Architecture & Design]
- 系统架构师要点总结(一) —— 软件架构设计
- 软件架构设计