C++智能指针(2)—— unique_ptr

本文深入探讨了C++中的unique_ptr,包括其禁止隐式构造、拷贝构造和赋值操作的特点。通过示例解释了为何在特定情况下可以使用右值引用进行拷贝构造。同时,介绍了右值引用的作用,即引用即将销毁的对象。此外,还展示了如何实现一个简单的unique_ptr类模板,包含移动构造和移动赋值操作。
摘要由CSDN通过智能技术生成

1、unique_ptr

①不能使用同一个裸指针赋值,或使用同一个裸指针初始化多个unique ptr
②不允许隐式构造

void text01()
{
	int* p = new int(10);
	unique_ptr<int> u_p=p;//报错,不允许隐式构造
	unique_ptr<int> u_p1(p);
	cout << *p << endl;
	cout << u_p << endl;
}
int main()
{
	text01();
	return 0;
}

③不允许拷贝构造,不允许等号运算符重载

void text01()
{
	int* p = new int(10);
	unique_ptr<int> u_p(p);
	unique_ptr<int> u_p1(p);
	u_p1 = u_p;//不允许等号运算符重载,会报错
	cout << *p << endl;
	cout << u_p << endl;
}
int main()
{
	text01();
	return 0;
}

但是为什么下面的程序却能够通过?

unique_ptr<int> fun(unique_ptr<int>& ptr)
{
	cout << *ptr << endl;
	int* p = new int(9);
	return unique_ptr<int>(p);
}
void text01()
{
	int* p = new int(10);
	unique_ptr<int>u_p(p);
	unique_ptr<int>u_p2(fun(u_p));//有拷贝构造的过程,但是能够运行通过
	cout << *u_p2 << endl;
}
int main()
{
	text01();
	return 0;
}

在这里插入图片描述
原因:
存在右值引用的等号运算符,右值引用的拷贝构造,就可以,而普通对象不能放在右值引用的拷贝构造或者等号运算符中。

2、右值引用

用来引用即将死亡的对象

void text02()
{
	const int& a = 10;
	int&& b = 10;
	//上面两行等价,如果只是int& a = 10,会报错,原因是a是一个不可取地址的量,10会产生临时量,具有常属性,所以对a前面加上const
	
	const int c = 10;
	const int& d = c;
	int&& e = c;//这行还会报错,所以右值引用并不是用来引用常量,而是临时对象
}

3、bool类型的重载

void text01()
{
	int* p = new int(10);
	unique_ptr<int>u_p(p);
	if (u_p)//将指针放在if的括号内,并不会出错
	{

	}
}

4、自己重写部分源码

template <typename T>
class Munique_ptr
{
public:
	//构造
	explicit Munique_ptr(T* ptr = nullptr)
		:_ptr(ptr)//explicit用来防止隐式构造
	{
	}
	//拷贝构造
	Munique_ptr(Munique_ptr& src) = delete;
	//等号运算符重载
	Munique_ptr operator=(Munique_ptr& src) = delete;
	//移动拷贝构造
	Munique_ptr(Munique_ptr&& src)
		:_ptr(src.release())
	{
	}
	//移动等号运算符重载
	Munique_ptr& operator=(Munique_ptr&& src)
	{
		_ptr = src.release();
	}
	~Munique_ptr()
	{
		delete _ptr;
		//unique_ptr的源码中有删除器,从而根据请款选择delete还是delete[],而本篇不妨写删除器部分
	}

	T* release()
	{
		T* tmp = _ptr;
		_ptr = nullptr;
		return tmp;
	}
	void reset()
	{
		delete _ptr;
		_ptr = nullptr;
	}
	T& operator*()
	{
		return *_ptr;
	}
	T* operator->()
	{
		return _ptr;
	}
	operator bool()
	{
		return _ptr != NULL;
	}
private:
	T* _ptr;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仟各

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值