简单的shared_ptr实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单的shared_ptr实现相关的知识,希望对你有一定的参考价值。
RT,代码参考了STL中shard_ptr的实现,基本原理是引用计数,利用Ref_cnt类来管理内存,在shared_ptr创建时创建,此后shared_ptr仅是在拷贝复制析构的过程中对引用进行修改,个人觉得比较有意思的一个地方在于通过对Ref_cnt类多态的应用使得shared_ptr无需额外增加模板参数这个想法(我原来想利用默认模板参数的方法感觉既不灵活又麻烦)。
#ifndef _TSHARED_PTR_ #define _TSHARED_PTR_ #include <cstdlib> #ifdef _N_C11 #define nullptr 0 #endif #include <cstdlib> namespace Tsp{ class Ref_cnt_base{ public: void decRef(){ if (--_cnt == 0){ this->_Destroy(); this->_Delete_this(); } } inline void incRef(){ _cnt++; } inline size_t _use_cnt(){ return _cnt; } Ref_cnt_base() :_cnt(1){} #ifndef _N_C11 ~Ref_cnt_base() = default; #endif protected: virtual void _Destroy() = 0; virtual void _Delete_this() = 0; size_t _cnt; }; template<typename T> class Ref_cnt :public Ref_cnt_base{ public: #ifndef _N_C11 Ref_cnt() = delete; #endif Ref_cnt(T*p) : Ref_cnt_base(), _ptr(p){} #ifndef _N_C11 ~Ref_cnt() = default; #endif private: #ifdef _N_C11 void _Destroy(){ delete _ptr; } void _Delete_this(){ delete this; } #endif #ifndef _N_C11 void _Destroy()override{ delete _ptr; } void _Delete_this()override{ delete this; } #endif T *_ptr; }; template<typename T, typename D> class Ref_cnt_del :public Ref_cnt_base{ public: #ifndef _N_C11 Ref_cnt_del() = delete; #endif Ref_cnt_del(T*p, D d) :Ref_cnt_base(), _ptr(p), deleter(d){} #ifndef _N_C11 ~Ref_cnt_del() = default; #endif private: #ifdef _N_C11 void _Destroy(){ deleter(_ptr); } void _Delete_this(){ delete this; } #endif #ifndef _N_C11 void _Destroy()override{ deleter(_ptr); } void _Delete_this()override{ delete this; } #endif T* _ptr; D deleter; }; template<typename T> class Tshared_ptr{ public: Tshared_ptr() :_ptr(nullptr), _rep(nullptr){} explicit Tshared_ptr(T *p) : _ptr(p), _rep(new Ref_cnt<T>(p)){} Tshared_ptr(const Tshared_ptr<T>&r) :_ptr(nullptr), _rep(nullptr){ if (r._rep != nullptr) r._rep->incRef(); _rep = r._rep; _ptr = r._ptr; } //should add a right value ref template<typename Dp> Tshared_ptr(T* p, Dp d) : _ptr(p), _rep(new Ref_cnt_del<T, Dp>(p, d)){} template<typename Dp> Tshared_ptr(const Tshared_ptr<T>&r, Dp d) : _ptr(r._ptr), _rep(new Ref_cnt_del<T,Dp>(r._ptr,d)){ this->_rep->incRef(); } virtual ~Tshared_ptr(){ if (_rep != nullptr) _rep->decRef(); } static void swap(Tshared_ptr<T>&p, Tshared_ptr<T>&q){ Tshared_ptr<T> tmp(p); p = q; q = tmp; } void swap(Tshared_ptr<T>&p){ Tshared_ptr<T> tmp(p); p = *this; *this = tmp; } inline size_t use_count()const{ return _rep ? _rep->_use_cnt() : 0; } inline bool isUnique_ptr(){ return use_count() == 1; } T* get()const{ return _ptr; } void reset(){ _rep->decRef(); _ptr = nullptr; _rep = nullptr; } template<typename D> void reset(Tshared_ptr<T> &p, D d){ _ptr = p->_ptr; _rep = new Ref_cnt_del<T, D>(_ptr, d); p._rep->incRef(); } bool operator == (const Tshared_ptr<T> &r)const{ return _rep == r._rep; } bool operator != (const Tshared_ptr<T> &r)const{ return !(*this == r); } Tshared_ptr<T>& operator = (const Tshared_ptr<T>&r){ if (r._rep != nullptr) r._rep->incRef(); if (_rep != nullptr) _rep->decRef(); _rep = r._rep; _ptr = r._ptr; return *this; } #ifndef _N_C11 explicit #endif operator bool() const{ return _ptr != nullptr; } T& operator* ()const{ return *_ptr; } T* operator ->()const{ return _ptr; } private: T* _ptr; Ref_cnt_base* _rep; }; template<typename T> Tshared_ptr<T> make_Tshared_pointer(T*p){ return Tshared_ptr<T>(p); } } #endif
以上是关于简单的shared_ptr实现的主要内容,如果未能解决你的问题,请参考以下文章