unique_ptr 和Scope_ptr

#include
using namespace std;

void func(int *ptr)
{
	int *p = new int;//
	if (ptr == NULL)
	{
		throw exception("ptr is NULL");
	}
	*p = *ptr;
	delete p;
}
//异常抛出点之前有动态内存申请,异常的话就从异常调用点跳出去了,动态内存释放就不会执行了。产生内存泄露
int main()
{
	func(NULL);
}

修改,给出auto_ptr智能指针。

#include
using namespace std;

void func(int *ptr)
{
	auto_ptr p(new int);
	if (ptr == NULL)
	{
		throw exception("ptr is NULL");
	}
	*p = *ptr;
}

int main()
{
	func(NULL);
}
//此时仅仅出现异常未处理程序崩溃的错误

旧的智能指针有释放权,新的有

旧的智能指针没有释放权,新的也没有

带有标志位(加入释放权)的智能指针unique_ptr  设计思想:管理员不唯一,释放权唯一

存在的问题:由于释放权的转移,导致堆内存可能提前释放,其他智能指针失效。

#include
using namespace std;
//unique_ptr
//带有标志位(加入释放权)的智能指针存在的问题:由于释放权的转移,导致堆内存可能提前释放,其他智能指针失效。
//实现旧的智能指针有释放权,新的有
//旧的智能指针没有释放权,新的也没有
template
class SmartPtr//智能指针对象,对堆内存进行管理
{
public:
	SmartPtr(T* ptr) :mptr(ptr)//构造函数
	{
		flag = true;
	}
	SmartPtr(const SmartPtr& rhs) :mptr(rhs.mptr)//拷贝构造   mptr(rhs.mptr)建立管理关系
	{
		//建立释放权
		flag = rhs.flag;
		rhs.flag = false;
	}
	//赋值运算符重载
	SmartPtr& operator=(const SmartPtr&rhs)
	{
		//防止自赋值
		if (this != &rhs)//旧资源:mptr指针指向的堆内存
		{
			~SmartPtr();
			mptr = rhs.mptr;
			flag = rhs.flag;
			rhs.flag = false;
		}
		return *this;
	}
	T& operator*()
	{
		return *mptr;
	}
	T* operator->()
	{
		return mptr;
	}
	~SmartPtr()
	{
		if (flag)
		{
			delete mptr;
		}
		mptr = NULL;
	}
private:
	
	T* mptr;//封装一个指针指向堆内存
	mutable bool flag;//mutable去常性
};

void func(SmartPtrsp)
{

}
int main()
{
	SmartPtr sp1(new int);//生成智能指针对象sp1  mptr指向new int堆内存  标志位flag=true
	SmartPtr sp2(sp1);
	//拷贝构造方式生成智能指针对象sp2,sp1和sp2智能指针均指向new int 这块堆内存
	//转移释放权,并将旧的智能指针中的flag=false。 则sp2有释放权,sp1没有释放权了
	SmartPtr sp3(sp1);//sp2生成时,sp1没有释放权了,所以sp3也没有释放权了
	//func(sp2);
	//实参传形参  初始化过程  拿sp2构建形参sp,调用拷贝构造函数,对sp进行构造,释放权就交给sp了,
	//sp的生命周期,func函数一旦调用完成就清理形参sp内存,形参对象要销毁,
	//三个智能指针指向的堆内存就被释放掉了。
	*sp1 = 20;//在此操作的是归还给系统的地址块,但new int 已经delete掉了,但是内存块还在堆上,
	//相当于拿到的是野指针,可以操作,但是这块内存有可能会被分配出去,导致数据出错。
	return 0;
}

Scope_ptr

#include
using namespace std;
//Scope_ptr  不允许多个智能指针指向同一块堆内存
template
class Scope_ptr
{
public:
	Scope_ptr(T* ptr)
	{
		mptr = ptr;
	}
	~Scope_ptr()
	{
		delete mptr;
		mptr = NULL;
	}
	T* operator->()
	{
		return mptr;
	}
	T& operator&()
	{
		return *mptr;
	}
private:
	Scope_ptr(const Scope_ptr& rhs);
	Scope_ptr& operator=(const Scope_ptr& rhs);
	T* mptr;
};
int main()
{
	int* p = new int;
	//手动让多个智能指针指向同一块堆内存
	Scope_ptr sp1(p);
	Scope_ptr sp2(p);
	Scope_ptr sp3(p);
	Scope_ptr sp4(p);
	//sp4先销毁,堆内存释放,sp2、sp3、sp4为野指针,一释放程序就崩溃
}

 

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