看了《Effective C++》中提到的TR1::shared_ptr,觉得很有用,就想尝试自己实现一个。一开始的想法很直接,就是两个模板参数一个代表所持有的指针类型,一个代表销毁资源的函数类型,默认为delete操作,于是有了第一个版本
- #ifndef SHARE_PTR_H_INCLUDED
- #define SHARE_PTR_H_INCLUDED
- namespace share_ptr
- {
- template<class T,class Func=void>
- class share_ptr
- {
- public:
- size_t* pCount;
- share_ptr(T* pt_,Func destoryFunc_):
- pt(pt_),destoryFunc(destoryFunc_)
- {
- pCount = new size_t(1);
- }
- share_ptr(const share_ptr&sp):
- pt(sp.pt),destoryFunc(sp.destoryFunc)
- {
- pCount=sp.pCount;
- (*pCount)++;
- }
- share_ptr& operator=(const share_ptr&sp)
- {
- release();
- pt = sp.pt;
- destoryFunc = sp.destoryFunc;
- pCount=sp.pCount;
- (*pCount)++;
- return *this;
- }
- ~share_ptr()
- {
- release();
- }
- T& operator*()const
- {
- return *pt;
- }
- T* operator->()const
- {
- return pt;
- }
- T* get() const
- {
- return pt;
- }
- private:
- T* pt;
- Func destoryFunc;
- void release()
- {
- *pCount)--;
- if(*pCount == 0 )
- {
- destoryFunc(pt);
- }
- }
- };
- // 特化,省略销毁函数时,默认用delete
- template<class T>
- class share_ptr<T,void>
- {
- public:
- typedef void (*freeFunc)(T* );
- size_t* pCount;
- share_ptr(T* pt_):
- pt(pt_)
- {
- pCount = new size_t();
- (*pCount)=1;
- }
- share_ptr(const share_ptr&sp):
- pt(sp.pt)
- {
- pCount=sp.pCount;
- (*pCount)++;
- }
- share_ptr& operator=(const share_ptr&sp)
- {
- release();
- pt = sp.pt;
- pCount=sp.pCount;
- (*pCount)++;
- return *this;
- }
- ~share_ptr()
- {
- release();
- }
- T& operator*()
- {
- return *pt;
- }
- T* operator->()
- {
- return pt;
- }
- T* get() const
- {
- return pt;
- }
- private:
- T* pt;
- void release()
- {
- (*pCount)--;
- if(*pCount == 0 )
- {
- delete pt;
- }
- }
- };
- }
- #endif // SHARE_PTR_H_INCLUDED
但是这个版本在要定义销毁函数时还需要声明销毁函数类型,用起来很麻烦,而且考虑到销毁函数只能有一个T*的参数,因此考虑将第二个模板参数定义为R,这样销毁函数可以用R (T*)来表示。于是有了第二个版本
- #ifndef SHARE_PTR_H_INCLUDED
- #define SHARE_PTR_H_INCLUDED
- namespace share_ptr
- {
- template<class T,class FreeFuncRetType=void>
- class share_ptr
- {
- public:
- typedef FreeFuncRetType(*FreeFuncType)(T*);
- size_t* pCount;
- template<class U>
- share_ptr(U* pt_,FreeFuncType destoryFunc_=NULL): //定义模板构造函数运用泛化的方式实现类似父类指针指向子类的功能
- pt(pt_), //确保T*可以被U*初始化
- destoryFunc(destoryFunc_)
- {
- pCount = new size_t(1);
- }
- share_ptr(const share_ptr&sp):
- pt(sp.pt),destoryFunc(sp.destoryFunc)
- {
- pCount=sp.pCount;
- (*pCount)++;
- }
- share_ptr& operator=(const share_ptr&sp)
- {
- release();
- pt = sp.pt;
- destoryFunc = sp.destoryFunc;
- pCount=sp.pCount;
- (*pCount)++;
- return *this;
- }
- ~share_ptr()
- {
- release();
- }
- T& operator*()const
- {
- return *pt;
- }
- T* operator->()const
- {
- return pt;
- }
- T* get() const
- {
- return pt;
- }
- private:
- T* pt;
- FreeFuncType destoryFunc;
- void release()
- {
- (*pCount)--;
- {
- if(*pCount == 0 )
- if(destoryFunc)
- {
- destoryFunc(pt);
- }
- else
- {
- delete pt;
- }
- }
- }
- };
- }
- #endif // SHARE_PTR_H_INCLUDED
这样使用起来就容易多了,但是还是需要有第二个模板参数。有没有可能省略第二个模板参数呢?路还很漫长啊~~