• 智能指针


    1.智能指针的分类

      shared_ptr 允许多个指针指向同一个对象

      unique_ptr 只允许唯一指针指向指定对象

      weak_ptr 弱引用,指向 shared_ptr 所管理的对象

      智能指针都定义在 memory 头文件中

    2.shared_ptr

      shared_ptr 是模板,创建时,必须提供指针指向的类型:

        shared_ptr<string> p1; // shared_ptr 可以指向string 

        shared_ptr<list<int>> p2; // shared_ptr 可以指向 int 的 list 

      默认初始化的智能指针中保存着一个空指针

    3.make_shared 函数

      shared_ptr<int> p3 = make_shared<int>(42); // 指向一个值为 42 的 int 的shared_ptr

      shared_ptr<string> p4 = make_shared<string>(5, 's'); // 指向一个值为 “sssss” 的 string

      shared_ptr<int> p5 = make_shared<int>(); // 指向一个值为 0 的 int

      auto p6 = make_shared<vector<string>>(); // 指向一个动态分配的空 vector<string>

    4.shared_ptr 拷贝和赋值

      auto p7 = make_shared<int>(2); // p7 指向的对象只有 p7 一个引用者

      auto p8(p7); // p7 和 p8 指向相同的对象,此对象有两个引用者

      引用计数:无论何时我们拷贝一个 shared_ptr,计数器都会递增,shared_ptr 赋予一个新值或被销毁,计数器就会递减。一旦一个 shared_ptr 计数器变为 0,它就会自动释放自己所管理的对象

    5.shared_ptr 和 new 结合使用

       shared_ptr<int> p9(new int(1024)); // 指向一个值为1024的 int

      尽量使用 make_shared 而不使用 new 

    6.定义和改变 shared_ptr 的其他方法

      shared_ptr<T> p(q) // p 管理内置指针 q 所指向的对象,q 必须指向 new 分配的内存,且能够转换为 T* 类型

      shared_ptr<T> p(u) // p 从 unique_ptr u 那里接管了对象的所有权,将 u 置空

      shared_ptr<T> p(q, d) // p 接管了内置指针 q 所指向的对象的所有权, q 必须能转换为 T* 类型, p 将使用可调用对象 d 来代替 delete

      shared_ptr<T> p(p2, d) // p 是 shared_ptr p2 的拷贝,唯一的区别是 p 将用可调用对象 d 来代替 delete

      p.reset(q, d) // 若 p 是唯一指向其对象的 shared_ptr, reset 会释放此对象, 若传递了可选的参数内置指针 q,会令 p 指向 q,否则会将 p 置为空,若还传递了参数 d,将会调用删除器 d 而不是 delete 来释放 q,reset 通常和 unique 一起使用

    7.不要混合使用普通指针和智能指针

       当将一个 shared_ptr 绑定到一个普通指针时,就不要再使用普通指针来访问 shared_ptr 所指向的内存了,也不要用 get 初始化另一个智能指针或为智能指针赋值

    8.智能指针使用原则

      不使用相同的内置指针初始化或 reset 多个智能指针

      不 delete get() 返回的指针

      不使用 get() 初始化或 reset 另一个智能指针

      如果使用 get() 返回的指针, 记住当最后一个对应的智能指针销毁后,该内置指针就已经变为无效

      如果使用智能指针管理的资源不是 new 分配的内存,记住传递给它一个删除器

    9.unique_ptr

      某个时刻只能有一个 unique 指向一个给定的对象,当 unique_ptr 被销毁时,它所指向的对象也被销毁

      make_shared 不能返回 unique_ptr ,所以定义 unique_ptr 时,需要将其绑定到一个 new 返回的指针上

        unique_ptr<int> p(new int(42)); // 指向一个值为42的int

      unique_ptr 不支持普通的拷贝或赋值操作

      unique_ptr<T, D> u(d); // 空 unique_ptr ,指向 T 类型的对象,用类型为 D 的对象代替 delete

      u = nullptr; // 释放 u 指向的对象,将 u 置空

      u.release(); // u 放弃对指针的控制权,返回指针,并将 u 置空

      u.reset(); // 释放 u 指向的对象

      u.reset(q); // 如果提供了内置指针 q, 令 u 指向这个对象,否则将 u 置空

      u.reset(nullptr);

      unique_ptr 虽然不能拷贝或赋值,但可以通过用 release 或 reset 将指针所有权从一个(非 const ) unique_ptr 转移给另一个 unique_ptr 

        unique_ptr<string> p2(p1.release());

        unique_ptr<string> p3(new string("Text"));

        p2.reset(p3.(release()));

      如果不用另外一个智能指针来保存 release 返回的指针,就要程序员自己负责资源释放

      不能拷贝 unique_ptr 的规则有一个例外,可以拷贝或赋值一个将要被销毁的unique_ptr,最常见的例子时从函数返回一个 unique_ptr

    10.auto_ptr

      早期版有 auto_ptr 类,具有一部分 unique_ptr 的特性,但不能在容器中保存 auto_ptr,也不能从函数返回 auto_ptr,虽然 auto_ptr 仍是标准库的一部分,但编程时应使用 unique_ptr

    11.向 unique_ptr 传递删除器

      重载一个 unique_ptr 中的删除器会影响到 unique_ptr 类型以及如何构造(或 reset) 该类型的对象,重载时,必须要在尖括号中指向的类型之后提供删除器类型,在创建或 reset 一个这种 unique_ptr 类型的对象时,必须提供一个指定类型的可调用对象(删除器)

        unique_ptr<objT, delT> p (new objT, fun);

    12.weak_ptr

      weak_ptr 是一种不控制所指向对象生存周期的智能指针,它指向由一个 shared_ptr 管理的对象,将一个weak_ptr 绑定到一个 shared_ptr 不会改变 shared_ptr 的引用计数,一旦 shared_ptr 被销毁,即使 有weak_ptr 指向对象,对象也还是会被释放

      创建一个 weak_ptr 时,要用一个 shared_ptr 来初始化它

        auto p = make_shared<int> (42);

        weak_ptr<int> wp(p);

      如果不能确定对象是否存在,不能用 weak_ptr 直接访问对象, 必须调用lock(),此函数检查 weak_ptr 指向的对象是否存在,如果存在,返回一个指向共享对象的 shared_ptr,如果不存在,返回一个空的 shared_ptr 

      

  • 相关阅读:
    LC 377. Combination Sum IV
    LC 718. Maximum Length of Repeated Subarray
    使用 Synchronized 关键字
    线程的基本概念
    谈谈 JAVA 的对象序列化
    JAVA 注解的基本原理
    基于 CGLIB 库的动态代理机制
    基于 JDK 的动态代理机制
    反射的基本原理
    泛型的基本原理
  • 原文地址:https://www.cnblogs.com/SmallAndGreat/p/12150244.html
Copyright © 2020-2023  润新知