weak_ptr
weak在英文中是弱的意思,那么相应的weak_ptr
就是弱指针,对应的shared_ptr
就是强指针。
weak_ptr
智能指针指向一个由shared_ptr
管理的对象,但是它不控制所指向对象的声明周期。换句话来说,就是将weak_ptr
绑定到由shared_ptr
管理的对象身上不会改变shared_ptr
的引用计数。更确切的说,weak_ptr
的构造和析构不会改变所指对象的引用计数。
当shared_ptr
需要释放所指的管理对象的时候照常释放,不会管有没有weak_ptr
指向该对象。
能力弱(弱共享/弱引用):共享其他shared_ptr
所指的对象,控制不了所指对象的生存期。
这个弱引用的作用可以理解成是监视强引用的生命周期用的,是对强引用的一种扩充。weak_ptr
不是一种独立的智能指针,不能用来操作所指向的资源,所以看起来像是shared_ptr
的一个助手或者旁观者。
weak_ptr
能够监视到它所指向的对象是否还存在。
创建weak_ptr
创建weak_ptr
的时间一般用一个shared_ptr
来初始化,所以在创建之前要有一个shared_ptr
智能指针。
cpp
#include <iostream>
using namespace std;
int main() {
std::shared_ptr<int> p1(new int(100));
std::weak_ptr<int> wp1(p1); //不会改变p1的强引用计数,但是会改变p1的弱引用计数
std::weak_ptr<int> wp2 = p1;
std::weak_ptr<int> wp3;
wp3 = p1;
cout << "p1=" << *p1 << endl;
cout << "wp1=" << *(wp1.lock()) << endl;
cout << "wp2=" << *(wp2.lock()) << endl;
cout << "wp3=" << *(wp3.lock()) << endl;
return 0;
}
程序输出:
bash
p1=100
wp1=100
wp2=100
wp3=100
weak_ptr
常用操作
lock()
:能够检查所指向的对象是否存在,如果存在返回一个指向该对象的shared_ptr
指针,相应的强引用计数会加1;如果对象不存在,会返回一个空的shared_ptr
指针。use_count()
获得与该弱指针共享对象的其他shared_ptr
的数量,或者说获得当前观察对象的强引用计数。expired()
是否过期的意思,若该指针的use_count
为0(表示该弱指针所指的对象已经不存在了),返回true
;否则返回false
。换句话说,这个函数用来判断所观测资源是否已经被释放。reset()
将该弱引用指针设置为空,不影响该对象的强引用数量,但指向该对象的弱引用数量会减少1。
尺寸问题
weak_ptr
和shared_ptr
的尺寸一样大,是原始指针的两倍。也就是说若原始指针占用4字节它就是8字节,若原始指针占用8字节它就是16字节。其时其内部包含两个原始指针。
通过上图我们可以发现其内部的两个原始指针一个指向该对象,另一个指向一个包含该对象某些属性信息的控制块(该控制块由shared_ptr
创建)