智能指针(三unique_ptr)

unique_ptr智能指针


为什么说unique_ptr是一个独享指针,体现在哪里?
unique_ptr对象始终是关联的原始指针的唯一所有者,因此在其析构函数中它直接删除关联的指针,不需要任何参考计数。我们无法复制unique_ptr对象,它只能移动。
示例:

unique_ptr<int>s_pa(new int(88));
unique_ptr<int>s_pb=move(s_pa);
这里是显式的所有权转移,C++11标准中才有的

unique_ptr的特点:

  • 不允许隐式构造
  • 不能将同一个裸指针赋值给多个智能指针
  • 不允许普通的拷贝构造和等号运算符重载(auto_ptr允许这种操作,是直接将原智能指针给置空了,而这里则直接不允许这种操作)
  • 允许对即将死亡的对象做拷贝构造和等号运算符重载 (这里还是会将原来的智能指针置空,但因为是将亡值,不会造成任何影响)
  • 消除资源直接使用deleter()(删除器:会自动区分是数组还是普通指针)
  • unique_ptr实际上是对auto_ptr的优化,区别不大,大部分功能都相同

创建空对象:

Munique_ptr<int> u_p1;
//因为没有与其关联的裸指针,所以是空的

创建对象:

    int* p = new int(10);
	Munique_ptr<int> u_p1(p);
	Munique_ptr<int> u_p2(p);//报错,每个unique_ptr对象都是裸指针的唯一所有者,不能共享

判空:
判空判断的是unique_ptr对象有没有与其关联的裸指针,有,则不为空,否则,则空

	operator bool()const//是否还拥有资源
	{
		return _ptr != NULL;
	}

可以对将亡值进行拷贝构造和等号运算符赋值
示例:

Munique_ptr<int> fun(Munique_ptr<int>& ptr)
{
	cout << *ptr << endl;
	return Munique_ptr<int>(new int(10));//new int(10)就是一个将亡值
}
Munique_ptr(const Munique_ptr&& src)
	//&&是右值引用,对于将亡值的引用,必须使用右值引用
	{
		if (this == &src)
		{
			return;
		}
		_ptr = src._ptr;
		src._ptr = NULL;//将 将亡值置空
	}
	Munique_ptr& operator=(Munique_ptr&& src)
	{
		if (this == &src)//防止自赋值
		{
			return *this;
		}
		delete _ptr;//这里还没有调用析构,在赋值之前,需要先delete指针
		_ptr = src._ptr;
		src._ptr = NULL;
		return *this;
	}

注意:对于将亡值的引用都是用右值引用
获取unique_ptr的内部指针:

	T* get()
	{
		return _ptr;
	}

释放unique_ptr对裸指针的所有权智能指针并返回():

	T* release()
	{
		T* tmp = _ptr;
		_ptr = NULL;
		return tmp;
	}

释放所有权并清空裸指针:

	void reset()
	{
		delete _ptr;
		_ptr = NULL;
	}

完整代码如下:

template<typename T>

class Munique_ptr
{
public:
	explicit Munique_ptr(T* ptr = NULL)//防止隐式构造
	{
		_ptr = ptr;
	}
	Munique_ptr(const Munique_ptr&& src)
	//&&是右值引用,对于将亡值的引用,必须使用右值引用
	{
		if (this == &src)
		{
			return;
		}
		_ptr = src._ptr;
		src._ptr = NULL;//将 将亡值置空
	}
	Munique_ptr& operator=(Munique_ptr&& src)
	{
		if (this == &src)//防止自赋值
		{
			return *this;
		}
		delete _ptr;//这里还没有调用析构,在赋值之前,需要先delete指针
		_ptr = src._ptr;
		src._ptr = NULL;
		return *this;
	}
	~Munique_ptr()//unique_ptr的析构函数
	{
		delete _ptr;
	}
	T* get()
	{
		return _ptr;
	}
	T* release()
	{
		T* tmp = _ptr;
		_ptr = NULL;
		return tmp;
	}
	void reset()
	{
		delete _ptr;
		_ptr = NULL;
	}
	T* operator->()
	{
		return _ptr;
	}
	T& operator*()
	{
		return *_ptr;
	}
	operator bool()const//是否还拥有资源
	{
		return _ptr != NULL;
	}
private:
	T* _ptr;
};

注意:这是unique_ptr实现将亡值的拷贝构造和赋值运算符重载函数的前提

Munique_ptr<int> fun(Munique_ptr<int>& ptr)
{
	cout << *ptr << endl;
	return Munique_ptr<int>(new int(10));//new int(10)就是一个将亡值
}
int main()
{
	int* p = new int(10);
	Munique_ptr<int> u_p1(p);
	//Munique_ptr<int> u_p2(p);//报错
	u_p1 = fun(u_p1);//将亡值的生存期仅限于这条语句
	//Munique_ptr<int>u_p4;
	cout << *u_p1 << endl;

	u_p1.get();
	u_p1.reset();
	u_p1.release();
	//u_p1.swap();//交换两个智能指针的内部指针
	//u_p1.operator bool();
	//u_p1.get_deleter();
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值