前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++】智能指针:weak_ptr

【C++】智能指针:weak_ptr

作者头像
灰子学技术
发布2020-12-08 17:02:18
9130
发布2020-12-08 17:02:18
举报
文章被收录于专栏:灰子学技术灰子学技术

一、产生原因

weak_ptr的产生,主要是为了配合shared_ptr的使用,对于shared_ptr来说,有一种循环引用会导致shared_ptr的引用计数一直不能变为0,如此以来导致内存一直不能释放的掉。例子可以参考下面例子:

代码语言:javascript
复制
#include <iostream>
#include <memory>
#include <vector>
using namespace std;

class ClassB;

class ClassA
{
public:
    ClassA() { cout << "ClassA Constructor..." << endl; }
    ~ClassA() { cout << "ClassA Destructor..." << endl; }
    shared_ptr<ClassB> pb;  // 在A中引用B,这里导致引用计数不能b看为0
};

class ClassB
{
public:
    ClassB() { cout << "ClassB Constructor..." << endl; }
    ~ClassB() { cout << "ClassB Destructor..." << endl; }
    shared_ptr<ClassA> pa;  // 在B中引用A 这里导致引用计数不能b看为0
};

int main() {
    shared_ptr<ClassA> spa = make_shared<ClassA>();
    shared_ptr<ClassB> spb = make_shared<ClassB>();
    spa->pb = spb;
    spb->pa = spa;
    // 函数结束,思考一下:spa和spb会释放资源么?
}
输出: // 不能释放掉分配的内存
ClassA Constructor...
ClassB Constructor...
Program ended with exit code: 0

除此之外,weak_ptr也具有弱引用特性,不拥有对象,只有延迟到尝试调用Lock()时才会有可能临时拥有对象:

只是持有一个没有拥有权的被shared_ptr托管的对象。 只有调用lock()创建shared_ptr指针时才会引用实际对象。

二、特性

weak_ptr的特性如下所示:

代码语言:javascript
复制
1.不具有普通指针的行为,没有重载operator*和->。
2.它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况。
3.weak_ptr可以从一个shared_ptr或者另一个weak_ptr对象构造,获得资源的观测权。
4.weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。

weak_ptr的使用特点:

代码语言:javascript
复制
1.使用weak_ptr的成员函数use_count()可以观测资源的引用计数,
另一个成员函数expired()的功能等价于use_count()==0,
但更快,表示被观测的资源(也就是shared_ptr的管理的资源)已经不复存在。
2.weak_ptr可以使用一个非常重要的成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象, 
从而操作资源。
3.当expired()==true的时候,lock()函数将返回一个存储空指针的shared_ptr。

三、常用操作示例

代码语言:javascript
复制
#include <memory>
#include <iostream>
 
int main()
{
   std::weak_ptr<int> w_ptr;
 
   {
      auto ptr = std::make_shared<int>(10);
      w_ptr = ptr;
      // 来查看shared_ptr的引用计数
      std::cout << "w_ptr.use_count() inside scope: " << w_ptr.use_count() << '\n';
      // 通过lock()来获取对应的shared_ptr
      auto obj = w_ptr.lock();
      std::cout <<  *obj <<std::endl;
      // expired()来判断对应的object有没有被删除
      std::cout << "w_ptr.expired() out of scope: " << std::boolalpha << w_ptr.expired() << '\n';
   
   }// 出了}之后,shared_ptr被释放,引用计数被置为0.
 
   std::cout << "w_ptr.use_count() out of scope: " << w_ptr.use_count() << '\n';
   std::cout << "w_ptr.expired() out of scope: " << std::boolalpha << w_ptr.expired() << '\n';
}
输出:
w_ptr.use_count() inside scope: 1
10
w_ptr.expired() out of scope: false
w_ptr.use_count() out of scope: 0
w_ptr.expired() out of scope: true

四、主要函数实现

weak_ptr的核心就是利用weak_count 替代了shared_count这一个引用计数。

源码解析,这里讲解的不错:

https://blog.csdn.net/FreeeLinux/article/details/54647666

补充资料: https://en.cppreference.com/w/cpp/memory/weak_ptr/weak_ptr https://www.jianshu.com/p/234b818f289a https://blog.csdn.net/Xiejingfa/article/details/50772571

https://segmentfault.com/a/1190000020811201

https://blog.csdn.net/FreeeLinux/article/details/54647666

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 灰子学技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档