c++:动态内存与智能指针(2)

1. unique_ptr

某个时刻只能由一个unique_ptr指向一个给定对象
定义一个unique_ptr时,需要将其绑定到一个new返回的指针上。类似shared_ptr,初始化unique_ptr必须采用直接初始化形式。

unique_ptr<double> p1;//可以指向一个double的unique_ptr
unique_ptr<int> p2(new int(42));//p2指向一个值为42的int

unique_ptr不支持普通的拷贝或赋值

unique_ptr<string> p1(new string("Stegosaurus"));
unique_ptr<string> p2(p1);//错误:unique_ptr不支持拷贝
unique_ptr<string> p3;
p3 = p2;//错误:unique_ptr不支持赋值
unique_ptr操作
unique_ptr< T > u1空unique_ptr,可以指向类型为T的对象。u1会使用delete来释放它的指针
unique_ptr< T,D > u2同上,u2用一个类型为D的可调用对象来释放它的指针
unique_ptr< T,D > u(d)空unique_ptr,指向类型为T的对象,用类型为D的对象d代替delete
u = nullptr释放u指向的对象,将u置为空
u.release()u放弃对指针的控制权,返回指针,并将u置为空
u.reset()释放u指向的对象
u.reset(q)如果提供了内置指针q,令u指向这个对象;否则将u置为空
u.reset(nullptr)

虽然不能拷贝或赋值unique_ptr,但可以通过调用release或reset将指针的所有权从一个(非const)unique_ptr转移给另一个unique。

//将所有权从p1(指向string Stegosaurus)转移给p2
unique_ptr<string> p2(p1.release());//release将p1置为空
unique_ptr<string> p3(new string("Trex"));
//将所有权从p3转移给p2
p2.reset(p3.release());//reset释放了p2原来指向的内存

release成员返回unique_ptr当前保存的指针并将其置为空,因此p2被初始化为p1原来保存的指针,而p1被置为空。
reset成员接受一个可选的指针参数,令unique_ptr重新指向给定的指针。如果unique_ptr不为空,它原来指向的对象被释放。因此上例中,对p2调用reset释放了用“Stegosaurus”初始化的string所使用的内存,将p3对指针的所有权转移给p2,并将p3置为空。
如果不用另一个智能指针来保存release返回的指针,我们的程序就要负责资源的释放

p2.release();//错误:p2不会释放内存,而且我们丢失了指针
auto p = p2.release;//正确:但我们必须记得delete(p)

2. 传递unique_ptr参数和返回unique_ptr

不能拷贝unique_ptr的规则有一个例外:我们可以拷贝或赋值一个将要被销毁的unique_ptr。比如从函数返回一个unique_ptr:

unique_ptr<int> clone(int p)
{
	return unique_ptr<int>(new int(p));
}

unique_ptr<int> clone(int p)
{
	unique_ptr<int> ret(new int(p));
	//...
	return ret;
}

编译器知道要返回的对象将要被销毁,在此情况下,编译期执行一种特殊的拷贝。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值