几种常用智能指针简单实现

Author:GuangshengZhou
QQ: 825672792

智能指针

C++内存回收机制全靠程序员手动解决, 很多时候稍不留神就会存在内存泄漏,造成严重后果。现代C++引入了智能指针,对内存进行动态管理(RAII),极大的提高了C++编程效率。
现在我们来实现几个常用的智能指针(auto_ptr、share_ptr、weak_ptr),加深对智能指针的理解。

auto_ptr 实现

template<typedef T>
class auto_ptr{
public:
	//desc: explicit显示申明,防止隐式转换带来隐患,比如赋值操作。(默认implicit)
	//用于构造函数,一个参数或者首参除外其他参数有默认值且只传首参时有效
	explicit auto_ptr(T *ptr):m_ptr(ptr), m_bown(m_ptr != nullptr){
	}
	~auto_ptr(){
		delete m_ptr;
	}

	auto_ptr(const auto_ptr<T> & autoptr):m_bown(autoptr.isown())m_ptr(autoptr.release()){
	}
	
	auto_ptr& operator =(const auto_ptr<T> & autoptr){
		if(&autoptr == this){
			return *this;
		}
		relsease();
		m_ptr = autoptr.release();
		return *this;
	}
	
	T& operator *(){
		return *m_ptr;
	}
	T* operator ->(){
		return m_ptr;
	}
	T* get() const {
		return m_ptr;
	}
	T* release(){
		T* bakptr = m_ptr;
		m_ptr = nullptr;
		m_bown = false;
		return bakptr ;
	}
	void reset(T* ptr){
		if(ptr != m_ptr){
			delete m_ptr;
			m_ptr = ptr;
		}
	}
	bool isown(){
		return m_bown;
	}
private:
	T * m_ptr;
	bool m_bown;
};

备注:因为auto_ptr 赋值拷贝均会引起对象变化,因此不能作为STL容器的元素,否则在操作过后容器中的元素为nullptr,悬空使用时会使程序崩溃

share_ptr 实现

template<typedef T>
class share_ptr{
public:
	share_ptr():m_pcount(new int(1)), m_ptr(nullptr){
		m_pwkcount = new int(0);
	}
	explicit share_ptr(T *ptr):m_ptr(ptr){
		if(m_ptr != nullptr){
			m_count = new int(1);
			m_pwkcount = new int(0);
		}
	}
	~share_ptr(){
		release();
	}

	share_ptr(const share_ptr<T> & shareptr):m_pcount(shareptr.m_pcount)m_ptr(shareptr.m_ptr){
		if(m_pcount != nullptr){
			++(*m_pcount);
		}
	}
	
	share_ptr& operator =(const share_ptr<T> & shareptr){
		if(&shareptr== this){
			return *this;
		}
		//relsease();
		m_ptr = shareptr.m_ptr;
		m_pcount = ++(*shareptr.m_pcount);
		return *this;
	}
	share_ptr(const weak_ptr<T> & weakptr){
		m_ptr = weakptr.m_ptr;
		m_pcount = weakptr.m_pcount ;
		m_pwkcount = weakptr.m_pwkcount
		if(*m_pcount == 0){
			m_ptr  = nullptr;
		}
	}
	T& operator *(){
		return *m_ptr;
	}
	T* operator ->(){
		return m_ptr;
	}
	T* get() const {
		return m_ptr;
	}
private:
	T* release(){
		--(*m_pcount);
		if(*m_pcount == 0){
			delete m_ptr;
			m_ptr = nullptr;
			delete m_pcount;
			if((*m_pwkcount) == 0)){
				delete m_pwkcount;
				m_pwkcount = nullptr;
			}
		}
	}
public:
	T * m_ptr;
	int  *m_pcount;
	int  *m_pwkcount;
};

weak_ptr 实现

template<typedef T>
class weak_ptr{
public:
	weak_ptr():m_pcount(nullptr), m_ptr(nullptr){
		m_pcount = new int(0);
		m_pwkcount= new int(0);
	}
	~weak_ptr(){
		release();
	}

	explicit weak_ptr(const share_ptr<T> & weakptr):m_pcount(weakptr.m_pcount)m_ptr(weakptr.m_ptr){
		if(m_pwkcount != nullptr){
			++(*m_pwkcount );
		}
	}
	explicit weak_ptr(const weak_ptr<T> & shareptr):m_pcount(shareptr.m_pcount)m_ptr(shareptr.m_ptr){
		if(m_pwkcount != nullptr){
			++(*m_pwkcount );
		}
	}
	
	weak_ptr& operator =(const weak_ptr<T> & weakptr){
		if(&weakptr== this){
			return *this;
		}
		//relsease();
		m_ptr = weakptr.m_ptr;
		m_pcount = weakptr.m_pcount;
		++(*m_pwkcount) ;
		return *this;
	}
	weak_ptr& operator =(const share_ptr<T> & shareptr){
		//relsease();
		m_ptr = shareptr.m_ptr;
		m_pcount = shareptr.m_pcount;
		++(*m_pwkcount) ;
		return *this;
	}
	
	share_ptr<T> lock(){
		return share_ptr<T>(*this);
	}
	bool expired(){
		if(m_pcount  != nullptr && *m_pcount != 0){
			return false;
		}
		return true;
	}
	
	T& operator *(){
		return *m_ptr;
	}
	T* operator ->(){
		return m_ptr;
	}
	T* get() const {
		return m_ptr;
	}
private:
	T* release(){
		--(*m_pwkcount);
		//weak_ptr 绝对不要操作share_ptr 内存
		if(*m_pcount == 0 && *m_pwkcount == 0){
			delete m_pcount;
			if((*m_pwkcount) == 0)){
				delete m_pcount;
				m_pcount= nullptr;
				delete m_pwkcount;
				m_pwkcount = nullptr;
			}
		}
	}
public:
	T * m_ptr;
	int  *m_pcount;
	int  *m_pwkcount;
};

总结

boost中智能指针实现比上面的实现复杂得多,但基本思想是一样的

发布了2 篇原创文章 · 获赞 2 · 访问量 393

猜你喜欢

转载自blog.csdn.net/u010158920/article/details/105115303
今日推荐