c++智能指针unique_ptr和weak_ptr

unique_ptr

unique_ptr简介

一个unique_ptr “拥有”它所指向的对象。与shared_ptr不同,某个时刻只能有一个unique_ptr指向一个给定的对象。即两个 unique_ptr 不能指向一个对象,unique_ptr 之所以叫这个名字,是因为它只能指向一个对象,即当它指向其他对象时,之前所指向的对象会被摧毁。其次,当 unique_ptr 超出作用域时,指向的对象也会被自动摧毁。与shared_ptr不同,没有类似make_shared的标准库函数返回一个unique_ptr。当我们定义一个unique_ptr时,需要将其绑定到一个new返回的指针上,与shared_ptr类似,初始化必须采用直接初始化的形式。与shared_ptr不同的是不能进行拷贝操作赋值操作。

unique_ptr的操作

unique_ptr< T >sp空智能指针
p将p用做一个条件判断,若p指向一个对象,为true
*p解引用p,获得他指向的对象
p->mem等价于(*p).mem
p.get()返回p中保存的指针,使用时要小心,若智能指针释放了其对象,返回的指针所指向的对象
swap(p,q)交换p和q的指针
p.swap(q)交换p和q的指针
p.release()p放弃对指针的控制权,返回指针,并并且将p置空。
p.reset()释放p指向的对象。
p.reset(e)如果提供了内置指针e,p指向这个对象;否则p置空
unique_ptr<int> p1;//正确,可以指向一个int的unique_ptr
unique_ptr<int> p2(new int (2));//正确,p2指向一个值为2的int
unique_ptr<int> p3(p2);//错误 不支持拷贝
unique_ptr<int> p4;
p4=p2;//错误 不支持赋值操作
unique_ptr<int>p5(p2.release());//release将p1置空,
unique_ptr<int>p6(new int(2));
p5.reset(p6.release())//reset释放了p5原先指向的内存,p6对指针的控制权给p5
p2.release()//错误,p2不会释放内存,丢失了内置的指针
auto p = p2.release()//正确,但是需要delete(p)

unique_ptr初始化

建议使用以下代码进行初始化

unique_ptr<Test> p1(new Test(100));

看一个例子:

#include<iostream>
#include<memory>
using namespace std;
int main(){
	int *a = new int(100);
	{
		unique_ptr<int> p1(a);
	}
	unique_ptr<int> p2(a);
	cout <<"a的值是" <<*p2<<endl; //输出的值1926192
} 

上面的代码会出现未定义的操作,出现的原因p1,p2相互独立的独享a,在p1作用域完成后,会是释放a内存,所以出现未定义的操作。

传递unique_ptr参数和返回unique_ptr

不能拷贝unique_ptr的规则有一个例外:我们可以拷贝或者赋值一个将要销毁的unique_ptr。最常见的例子就是从函数返回一个unique_ptr:

#include<iostream>
#include<memory>
using namespace std;
unique_ptr<int> clone(int p){
	return unique_ptr<int>(new int(p));
}
int main(){
	unique_ptr<int> p2=clone(20);
	cout <<"a的值是" <<*p2<<endl;//输出20 
} 

还可以返回一个局部对象的拷贝;

#include<iostream>
#include<memory>
using namespace std;
unique_ptr<int> clone(int p){
	 unique_ptr<int> ret(new int(p));
	 return ret;
}
int main(){
	unique_ptr<int> p2=clone(20);
	cout <<"a的值是" <<*p2<<endl; //输出20 
} 

上边两段代码,编译器都知道要返回的对象将要被销毁。在此情况下,编译器执行一种特殊的“拷贝”。

weak_ptr

weak_ptr简介

weak_ptr是一种不控制所指向对象生存期的智能指针,他指向由一个shared_ptr管理的对象,将一个weak_ptr对象绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放,即使有weak_ptr指向对象,对象还是被释放的。

weak_ptr操作

weak_ptr< T >w空智能指针
weak_ptr<T> w(sp)与shared_ptr sp指向相同对象的weak_ptr.
w=pp可以是shared_ptr或者weak_ptr,赋值后w与p共享对象
w.reset()w置空
w.use_count()与w共享对象shared_ptr的数量
w.expired()若w.use_count()==0,返回true,否则返回false
w.lock()如果expired为true,返回一个空shared_ptr,否则返回一个指向w对象的shared_ptr。

当我们创建一个weak_ptr时我们需要用shared_ptr初始化

auto p = make_shared<int>(42)
weak_ptr<int>wp(p)//p的引用计数不会改变

由于weak_ptr的对象有可能不存在,所以访问的时候我们必须用lock。

if(shared_ptr<int>sp = wp.lock()){
	//sp和p共享对象
}
#include<iostream>
#include<memory>
using namespace std;
int main(){
	auto p = make_shared<int>(42);
	weak_ptr<int>wp(p);//p的引用计数不会改变
	if(shared_ptr<int>sp = wp.lock()){
		//sp和p共享对象
		*sp = 72;
	}
	cout << *p << endl; //输出72
} 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值