Skip to content

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_ptrshared_ptr的尺寸一样大,是原始指针的两倍。也就是说若原始指针占用4字节它就是8字节,若原始指针占用8字节它就是16字节。其时其内部包含两个原始指针。

通过上图我们可以发现其内部的两个原始指针一个指向该对象,另一个指向一个包含该对象某些属性信息的控制块(该控制块由shared_ptr创建)