C++ 智能指针
C++ 智能指针
为了更安全地使用动态对象,标准库定义了两个只能指针类型来管理动态分配的对象当一个对象应该被释放时,指向它的智能指针可以确保自动地把它释放。
理论上来说,一共有三个类型:
shared_ptr
unique_ptr
weak_ptr
本文主要介绍shared_ptr
和weak_ptr
。
简介
shared_ptr
允许多个指针指向同一个对象。unique_ptr
则“独占”所指向的对象。weak_ptr
是一个弱引用,指向由shared_ptr
管理的对象,但是不改变引用计数
shared_ptr
首先要介绍make_shared()
函数,顾名思义就是在动态内存中分配一个对象,并返回shared_ptr
,说白了就是让一段动态内存让shared_ptr
去管理,使用的时候对特定类型构造时必须与其构造函数相匹配,例如:
shared_ptr<int> p = make_shared<int>(1);
shared_ptr
允许多个指针指向同一个对象,并且还有一个与之关联的引用计数
,当拷贝shared_ptr
时这个计数器会增加,书中提到两点:
参数传递
函数值返回
函数值返回很好理解,参数传递是指在函数调用时实参到形参的值传递时的一个拷贝,这样,在函数内部,引用计数+1,当函数调用完成后(局部变量自动销毁),引用计数减1。
使用shared_ptr
管理内存十分有用,我们通常使用new
和delete
进行动态内存管理,但是如果出现下述情况:
int *p=new int(4);
//do something
//exception
delete p;
正如上述代码,如果在delete
之前发生异常并且没有被捕获,那么这块内存就永远不会被释放了。而使用shared_ptr
就不会出现这些问题,因为当与由智能指针管理的对象相关的计数器为0时,原本指向的对象就会自动被释放。
weak_ptr
指向由shared_ptr
管理的对象,与shared_ptr
共享不同,weak_ptr
只是一个弱引用,他不改变与对象相关的引用计数,通过单步调试可以清楚看见:
auto r = make_shared<int>(42);
weak_ptr<int>wp = r;
shared_ptr<int> p = make_shared<int>();
r = p;
如下图:
一开始r指针的强引用(strong refs)和弱引用(weak refs)都是1,而p与r独立。
而当将p赋值给r之后,r指向了p所管理的内存,而自己原先管理的内存被释放掉,由于 weak_ptr
不改变引用计数只起一个监控的作用,此时其状态已经变成了 expired
,书中也称作 伴随指针。
这里weak_ptr
主要的两个函数:
expired()
lock()
我们知道weak_ptr
指向由shared_ptr
管理的内存,那么当引用计数变为0时(此时根据shared_ptr
的机制会自动释放管理的内存),weak_ptr
就会呈现expired状态,即expired()
返回true。
std::shared_ptr<int> shared(new int(10));
std::weak_ptr<int> weak(shared);
std::cout << "1. weak " << (weak.expired() ? "is" : "is not") << " expired\n";
shared.reset();
std::cout << "2. weak " << (weak.expired() ? "is" : "is not") << " expired\n";
system("pause");
return 0;
运行结果:
而对于 lock()
函数来说,如果 expired()
为true,则返回一个空的 shared_ptr
,否则返回一个指向该 weak_ptr
所指向的对象的 shared_ptr
。
参考:
http://www.cplusplus.com/reference/memory/weak_ptr/expired/
http://blog.csdn.net/zhangxiao93/article/details/50570531
还没有评论,来说两句吧...