• c++11 智能指针 (std::shared_ptr)(三)


      定义于头文件 
    template< class T > class shared_ptr;     (C++11 起) 


    返回存储的指针

    std::shared_ptr<T>::get
    1. T* get() const noexcept; (C++17 前)
    2. element_type* get() const noexcept; (C++17 起)

    返回存储的指针。

    参数

    (无)

    返回值

    存储的指针。

    注意

    shared_ptr 可能在存储指向一个对象的指针时共享另一对象的所有权。 get() 返回存储的指针,而非被管理指针。

    调用示例

    1. #include <iostream>
    2. #include <memory>
    3. #include <string>
    4. void output(std::string msg, int const* pInt)
    5. {
    6. std::cout << msg << *pInt << "\n";
    7. }
    8. int main()
    9. {
    10. int* pInt = new int(42);
    11. std::shared_ptr<int> pShared = std::make_shared<int>(42);
    12. output("Naked pointer ", pInt);
    13. // output("Shared pointer ", pShared); // 编译错误
    14. output("Shared pointer with get() ", pShared.get());
    15. delete pInt;
    16. }

    输出

    解引用存储的指针

    1. std::shared_ptr<T>::operator*,
    2. std::shared_ptr<T>::operator->
    1. T& operator*() const noexcept; (1)
    2. T* operator->() const noexcept; (2)

    解引用所存储的指针。若存储的指针为空,则行为未定义。

    参数

    (无)

    返回值

    1) 解引用存储的指针所得的结果,即 *get()

    2) 存储的指针,即 get()

    注意

    T 是(可有 cv 限定的) void 类型时,是否声明函数 (1) 是未指定的。

    T 是数组类型时,是否声明这两个函数是未指定的。

    (C++17 起)

    以上情况下,若声明函数,则其返回类型是未指定的,但保证函数声明合法,函数定义未必合法。这使得 std::shared_ptr 可以实例化。

    调用示例

    1. #include <iostream>
    2. #include <memory>
    3. struct Foo
    4. {
    5. Foo(int in) : a(in) {}
    6. void print() const
    7. {
    8. std::cout << "a = " << a << '\n';
    9. }
    10. int a;
    11. };
    12. int main()
    13. {
    14. auto ptr = std::make_shared<Foo>(10);
    15. ptr->print();
    16. (*ptr).print();
    17. }

    返回 shared_ptr 所指对象的引用计数

    std::shared_ptr<T>::use_count
    long use_count() const noexcept;

    返回管理当前对象的不同 shared_ptr 实例(包含 this )数量。若无管理对象,则返回 ​0​ 。

    多线程环境下, use_count 返回的值是近似的(典型实现使用 memory_order_relaxed 加载)

    参数

    (无)

    返回值

    管理当前对象的 shared_ptr 实例数量,或若无被管理对象则为 ​0​ 。

    注意

    常用使用包括

    • 与 ​0​ 比较。若 use_count 返回零,则智能指针为且不管理对象(无论被存储指针是否为空)。多线程环境下,这不隐含被管理对象的析构函数已完成。
    • 与 1 比较。若 use_count 返回 1 ,则无其他拥有者。(被弃用成员函数 unique() 为此使用情况提供。)多线程环境中,这不隐含对象可以安全修改,因为先前拥有者对被管理对象的访问可能未完成,而因为新的共享拥有者可以同时引入,例如用 std::weak_ptr::lock 。

    调用示例 

    1. #include <memory>
    2. #include <iostream>
    3. void fun(std::shared_ptr<int> sp)
    4. {
    5. std::cout << "fun: sp.use_count() == " << sp.use_count() << '\n';
    6. }
    7. int main()
    8. {
    9. auto sp1 = std::make_shared<int>(5);
    10. std::cout << "sp1.use_count() == " << sp1.use_count() << '\n';
    11. fun(sp1);
    12. }

    输出

    检查是否有关联的管理对象

    std::shared_ptr::operator bool
    explicit operator bool() const noexcept;

    检查 *this 是否存储非空指针,即是否有 get() != nullptr 。

    参数

    (无)

    返回值

    若 true 存储非空指针则为 *this ,否则为 false 。

    注意

    空 shared_ptr (其中 use_count() == 0 )可能存储能以 get() 访问的非空指针,例如若它以别名使用构造函数创建。

    调用示例

    1. #include <iostream>
    2. #include <memory>
    3. void report(std::shared_ptr<int> ptr)
    4. {
    5. if (ptr) {
    6. std::cout << "*ptr=" << *ptr << "\n";
    7. } else {
    8. std::cout << "ptr is not a valid pointer.\n";
    9. }
    10. }
    11. int main()
    12. {
    13. std::shared_ptr<int> ptr;
    14. report(ptr);
    15. ptr = std::make_shared<int>(7);
    16. report(ptr);
    17. }

    输出

    提供基于拥有者的共享指针排序

    std::shared_ptr<T>::owner_before
    1. template< class Y >
    2. bool owner_before( const shared_ptr<Y>& other) const noexcept;
    3. template< class Y >
    4. bool owner_before( const std::weak_ptr<Y>& other) const noexcept;

    以实现定义的基于拥有者(与基于值相反)顺序,检查此 shared_ptr 是否先于 other 。二个智能指针仅若都占有同一对象或均为空才比较相等,即使由 get() 获得的指针不同(例如因为它们指向同一对象中的不同子对象)。

    此顺序用于令共享和弱指针可用作关联容器中的关键,通常经由 std::owner_less 。

    参数

    other-要比较的 std::shared_ptr 或 std::weak_ptr

    返回值

    若 *this 前于 other 则为 true ,否则为 false 。常见实现比较控制块的地址。

    调用示例

    1. #include <iostream>
    2. #include <memory>
    3. struct Foo
    4. {
    5. int n1;
    6. int n2;
    7. Foo(int a, int b) : n1(a), n2(b) {}
    8. };
    9. int main()
    10. {
    11. auto p1 = std::make_shared<Foo>(1, 2);
    12. std::shared_ptr<int> p2(p1, &p1->n1);
    13. std::shared_ptr<int> p3(p1, &p1->n2);
    14. std::cout << std::boolalpha
    15. << "p2 < p3 " << (p2 < p3) << '\n'
    16. << "p3 < p2 " << (p3 < p2) << '\n'
    17. << "p2.owner_before(p3) " << p2.owner_before(p3) << '\n'
    18. << "p3.owner_before(p2) " << p3.owner_before(p2) << '\n';
    19. std::weak_ptr<int> w2(p2);
    20. std::weak_ptr<int> w3(p3);
    21. std::cout
    22. // << "w2 < w3 " << (w2 < w3) << '\n' // won't compile
    23. // << "w3 < w2 " << (w3 < w2) << '\n' // won't compile
    24. << "w2.owner_before(w3) " << w2.owner_before(w3) << '\n'
    25. << "w3.owner_before(w2) " << w3.owner_before(w2) << '\n';
    26. }

    输出

  • 相关阅读:
    【LeetCode】一周中的第几天+ 一年中的第几天
    Poco库使用:操作Json格式数据
    gin框架初识
    37. 字典名[键名]=新值 修改字典的的值
    读书笔记|《数据压缩入门》—— 柯尔特·麦克安利斯 亚历克斯·海奇
    怎样生成分布式的流水ID
    xlsxStyle + xlsx.full.min 导出数据,并设置导出样式
    DS 顺序表--类实现(C++数据结构题)
    Web前端项目-页面动态背景【附完整源码】
    (done) win11 如何安装 Anaconda3 ? 如何安装 jupyter notebook
  • 原文地址:https://blog.csdn.net/qq_40788199/article/details/126696235