• c++ 智能指针 (std::weak_ptr)(二)


    定义于头文件

    template< class T > class weak_ptr;    (C++11 起) 

    std::weak_ptr 是一种智能指针,它对被 std::shared_ptr 管理的对象存在非拥有性(「弱」)引用。在访问所引用的对象前必须先转换为 std::shared_ptr。

    std::weak_ptr 用来表达临时所有权的概念:当某个对象只有存在时才需要被访问,而且随时可能被他人删除时,可以使用 std::weak_ptr 来跟踪该对象。需要获得临时所有权时,则将其转换为 std::shared_ptr,此时如果原来的 std::shared_ptr 被销毁,则该对象的生命期将被延长至这个临时的 std::shared_ptr 同样被销毁为止。

    std::weak_ptr 的另一用法是打断 std::shared_ptr 所管理的对象组成的环状引用。若这种环被孤立(例如无指向环中的外部共享指针),则 shared_ptr 引用计数无法抵达零,而内存被泄露。能令环中的指针之一为弱指针以避免此情况。
     

    特化 std::swap 算法

    std::swap(std::weak_ptr)
    1. template< class T >
    2. void swap( weak_ptr<T>& lhs, weak_ptr<T>& rhs ) noexcept; (C++11 起)

    为 std::weak_ptr 特化 std::swap 算法。交换 lhsrhs 的指针。调用 lhs.swap(rhs) 。

    参数

    lhs, rhs-要交换内容的智能指针

    返回值

    (无)

    复杂度

    常数

    调用示例

    1. #include <memory>
    2. #include <iostream>
    3. struct Foo
    4. {
    5. int N;
    6. Foo(int n): N(n) {}
    7. };
    8. int main()
    9. {
    10. std::shared_ptr<Foo> ptr_1 = std::make_shared<Foo>(1);
    11. std::shared_ptr<Foo> ptr_2 = std::make_shared<Foo>(2);
    12. std::weak_ptr<Foo> w_ptr1 = ptr_1;
    13. std::weak_ptr<Foo> w_ptr2 = ptr_2;
    14. {
    15. std::shared_ptr<Foo> ptr1 = w_ptr1.lock() ;
    16. std::shared_ptr<Foo> ptr2 = w_ptr2.lock() ;
    17. std::cout << "ptr1 N: " << ptr1->N << '\n';
    18. std::cout << "ptr2 N: " << ptr2->N << '\n';
    19. }
    20. {
    21. std::swap(w_ptr1, w_ptr2);
    22. std::shared_ptr<Foo> ptr1 = w_ptr1.lock() ;
    23. std::shared_ptr<Foo> ptr2 = w_ptr2.lock() ;
    24. // 只交换std::weak_ptr
    25. std::cout << "ptr1 N: " << ptr1->N << '\n';
    26. std::cout << "ptr2 N: " << ptr2->N << '\n';
    27. // 不交换std::shared_ptr
    28. std::cout << "ptr_1 N: " << ptr_1->N << '\n';
    29. std::cout << "ptr_1 N: " << ptr_2->N << '\n';
    30. }
    31. }

    输出

     

    返回管理该对象的 shared_ptr 对象数量

    std::weak_ptr<T>::use_count
    long use_count() const noexcept;  (C++11 起) 

    返回共享被管理对象所有权的 shared_ptr 实例数量,或 ​0​ ,若被管理对象已被删除,即 *this 为空。

    参数

    (无)

    返回值

    在调用的瞬间共享被管理对象所有权的 shared_ptr 实例数量。

    注意

    expired() 可能快于 use_count() 。此函数固有地有不稳,若被管理对象在可能创建并销毁 shared_ptr 副本的线程间共享:则结果仅若匹配调用方线程所独占的副本数或零才可靠;任何其他值可能在能使用前就变得过时了。

    调用示例

    1. #include <memory>
    2. #include <iostream>
    3. int main()
    4. {
    5. std::shared_ptr<int> s_ptr = std::make_shared<int>(3);
    6. std::weak_ptr<int> w_ptr = s_ptr;
    7. std::cout << "w_ptr.use_count() out of scope: " << w_ptr.use_count() << '\n';
    8. std::cout << "w_ptr.expired() out of scope: " << std::boolalpha << w_ptr.expired() << '\n';
    9. std::shared_ptr<int> s_ptr1 = s_ptr;
    10. std::cout << "w_ptr1.use_count() out of scope: " << w_ptr.use_count() << '\n';
    11. std::cout << "w_ptr1.expired() out of scope: " << std::boolalpha << w_ptr.expired() << '\n';
    12. s_ptr1.reset();
    13. std::cout << "w_ptr1.use_count() out of scope: " << w_ptr.use_count() << '\n';
    14. std::cout << "w_ptr1.expired() out of scope: " << std::boolalpha << w_ptr.expired() << '\n';
    15. }

    输出

     

    检查被引用的对象是否已删除

    std::weak_ptr<T>::expired
    bool expired() const noexcept;   (C++11 起) 

    等价于 use_count() == 0 。可能仍未对被管理对象调用析构函数,但此对象的析构已经临近(或可能已发生)。

    参数

    (无)

    返回值

    若被管理对象已被删除则为 true ,否则为 false 。

    注意

    若被管理对象在线程间共享,则此函数内在地不可靠,通常 false 结果可能在能用之前就变得过时。 true 结果可靠。

    调用示例

    1. #include <iostream>
    2. #include <memory>
    3. std::weak_ptr<int> gw;
    4. void f()
    5. {
    6. if (!gw.expired())
    7. {
    8. std::cout << "gw is valid\n";
    9. }
    10. else
    11. {
    12. std::cout << "gw is expired\n";
    13. }
    14. }
    15. int main()
    16. {
    17. {
    18. auto sp = std::make_shared<int>(42);
    19. gw = sp;
    20. f();
    21. }
    22. f();
    23. }

    输出

     

  • 相关阅读:
    优信电子所有博客汇总(导航搜索)
    【毕业设计】基于单片机无线充电的4轴飞行器 -物联网 嵌入式 stm32
    .Net分表分库动态化处理
    SPI传输出现数据与时钟不匹配延后问题分析与解决
    css第九课:文本属性
    【计算机基础】优雅的PPT就应该这样设计
    DPU — 功能特性 — 安全系统的硬件卸载
    基础复习——为activity补充活动信息——利用资源文件配置字符串——利用元数据传递配置信息——给页面注册快捷方式...
    内核开发-同步场景与概念
    scikit-learn算法精讲 之 层次聚类和树状图
  • 原文地址:https://blog.csdn.net/qq_40788199/article/details/126794579