C++智能指针简易实现

为什么需要智能指针

智能指针的作用在于帮助程序员回收不再使用的内存。c/c++程序员都知道,堆内存的申请和释放是由程序员自己控制的,在提升灵活性的同时,我们也常常因为内存异常而头疼,相信每个c/c++程序员都遇到过内存泄露、内存溢出或着是因为使用悬垂指针而导致程序崩溃,这种问题往往不容易被找到。

普通指针容易碰到的问题

  1. 忘记释放内存,导致内存耗尽后程序崩溃。
  2. 提前释放了内存,导致其他指针变成悬垂指针,在被使用时造成程序崩溃。

智能指针

智能指针的出现,能有效避免普通指针遇到的问题,因为他不需要程序员手动释放内存。

在c++中已经有标准的智能指针,网上也有很多很好的教程告诉大家如何使用。接下来本文主要介绍一下智能指针的实现原理和框架。

智能指针其实是一个标准的c++类。首先,这个类得拥有普通指针的基本功能,这需要重载:" = " 、" * " 、" -> "、等操作符。然后,这个类能合理的自己释放指针中的内容,这是智能指针的关键:引用计数。

什么是引用计数,举个通俗的例子:学校有个闲置的电脑提供给同学们用,并且有个小程序记录当前有几个人要用电脑。这时A去学校用电脑,把电脑开机,小程序上+1(计数1),A还在使用时,B来学校用电脑,这时小程序上又+1(计数2)。过了一会,A用完了电脑,在小程序上-1(计数1),正常来说应该把电脑关机,但是小程序上计数为1,说明还有1个人要用电脑。而后B同学也用完了,B同学也在小程序上-1(计数0),小程序检测到计数为0了,就知道没人要用电脑,于是把电脑关机。

例子中:操作系统就是电脑,开机就是申请内存,关机就是释放内存,小程序就是智能指针,使用者A和B不需要关心自己要不要关机(释放内存),他们只需要开机(申请内存)然后尽情的使用就可以了,小程序会根据(引用)计数判断当前是否要关机(释放内存)。

上代码:

#pragma once

template 
class MySmartPtr;

template 
class U_Ptr
{
	friend class MySmartPtr;
public:
	U_Ptr(T *p) :count_(1),p_(p) {};
	~U_Ptr() {
		delete p_;
	};

private:
	int count_;
	T *p_;
};

template 
class MySmartPtr
{
public:
	MySmartPtr(T *p) :up_(new U_Ptr(p)){};
	MySmartPtr(const MySmartPtr &sp) :up_(sp.up_) { ++up_->count_; };

	~MySmartPtr() {
		--up_->count_;
		if (up_->count_ == 0)
		{
			delete up_;
		}
		else
		{
			//cout << "还有" << rp->count << "个指针指向基础对象" << endl;
		}
	};

	MySmartPtr& operator = (const MySmartPtr &rhs) {
		++rhs.up_->count_;
		--up_->count_;
		if (up_->count_ == 0)
		{
			delete up_;
		}
		up_ = rhs.up_;
		return *this;
	};

	T& operator * () {
		return *(up_->p_);
	};

	T* operator -> () {
		return up_->p_;
	};

private:
	U_Ptr *up_;
};

最后提一提这个智能指针的几个问题:

  1. 不能解决循环引用问题(weak_ptr)
  2. 不能解决线程安全问题
  3. 不能解决从一般指针获得shared_ptr问题(enable_shared_from_this)
  4. 不能解决多态指针类型转换问题(dynamic_pointer_cast static_pointer_cast)
  5. 不能通过特化解决指向数组的问题,(std::unique_ptr)

你可能感兴趣的:(c++)