六一的部落格


关关难过关关过,前路漫漫亦灿灿。



smart pointer

模板类: 创建智能指针时, 需提供所指对象的类型

提供机制管理动态对象, 在满足条件的情况下自动销毁其所管理的动态对象

智能指针
shared_ptr 允许多个shared_ptr共同管理同一个动态对象
unique_ptr 独占管理的动态对象
weak_ptr 伴随指针; 弱引用; 可以通过weak_ptr访问share_ptr管理的动态对象, 较内置指针更安全

头文件

1#include <memory>

shared_ptr和unique_ptr的共同操作


创建智能指针


创建空指针

未指向任何动态对象

1shared_ptr<T> sp;
2unique_ptr<T> up;
  • 示例

    1shared_ptr<string> sp1;
    2shared_ptr<list<int>> sp2;
    3
    4unique_ptr<double> up1;
    5unique_ptr<string> up2;

使用内置指针初始化智能指针

内置指针到智能指针是显式转换

  • 使用new运算符为智能指针申请动态内存

    存在一次转换: 内置指针转换为智能指针

    1. new运算符返回指向动态对象的内置指针
    2. 内置指针到智能指针的转换构造函数是explicit的
    1shared_ptr<T> sp(new T(args));
    2unique_ptr<T> up(new T(args));
    • 内置指针到智能指针的转换构造函数是explicit的

      1shared_ptr<T> sp = new T(args); // 错误
      2unique_ptr<T> up = new T(args); // 错误
      
      1shared_ptr<T> sp = shared_ptr<T>(new T(args)); // 正确
      2unique_ptr<T> up = unique_ptr<T>(new T(args)); // 正确
      
    • 示例: 使用new运算符返回的内置指针初始化智能指针

      1shared_ptr<int> p1(new int(10));
      2shared_ptr<int> p2 = shared_ptr<int>(new int(20));
      3
      4unique_ptr<int> p3(new int(42));
      5unique_ptr<string> p4(new string("Stegosaurus"));
      6unique_ptr<int> p5 = unique_ptr<int>(new int(10));
  • 内置指针将动态对象托管给智能指针

    托管后, 建议将内置指针置空

     1auto p1 = new T(args);
     2auto p2 = new T(args);
     3auto p3 = new T(args);
     4auto p4 = new T(args);
     5
     6shared_ptr<T> sp1(p1);
     7unique_ptr<T> up1(p2);
     8
     9shared_ptr<T> sp2 = shared_ptr<T>(p3);
    10unique_ptr<T> up2 = unique_ptr<T>(p4);
    11
    12p1 = p2 = p3 = p4 = nullptr;

解引用智能指针

*

要求智能指针非空

获取所指对象的引用

1*p;
  • 示例

    1shared_ptr<string> p1(new string);
    2if (p1 && p1->empty())
    3    *pi = "hi";
    4
    5// 首先是p1不为空,其次要求其指向一个空串
    

从内置指针接管动态对象

1auto p5 = new T(args);
2auto p6 = new T(args);
3
4sp1 = shared_ptr<T>(p5);
5up1 = unique_ptr<T>(p6);
6
7p5 = p6 = nullptr;

访问动态对象

  1. p指向是否为空

  2. 获取对象的引用

    不要解引用一个空指针

  3. 访问对象成员

1p;
2*p;
3p->mem;

示例

1shared_ptr<string> sp(new string);
2
3if (sp && sp->empty())
4{
5    *sp = "hi";
6}
7cout << *sp << endl;

get成员函数: 获取指向动态对象的内置指针

返回一个内置指针,指向智能指针管理的动态对象

实为智能指针到内置指针的转换

1T *pt = p.get();

通过内置指针使用动态对象期间,需要保证动态对象不被销毁

  1. 将管理动态对象的唯一一个shared_ptr置空, 触发动态对象销毁

    1shared_ptr<string> sp(new string("hello"));
    2string *ps = sp.get();
    3cout << *ps << endl;
    4sp = nullptr;     // 动态对象被销毁
    5string s = *ps;   // 错误: 访问非法内存
    6cout << s << endl;
  2. 管理动态对象的唯一一个shared_ptr在块结束时被销毁, 触发动态对象销毁

    sp和sp2的计数器不共用; 二者均以为自己是管理动态对象的唯一一个shared_ptr

    1shared_ptr<string> sp(new string("hello"));
    2string *p = sp.get();
    3cout << *p << endl;
    4{
    5    shared_ptr<string> sp2(p);
    6}                 // 动态对象被销毁
    7string foo = *sp; // 错误: 访问非法内存
    8cout << foo << endl;

通过内置指针访问动态对象时, 不能对该指针执行delete操作,更不能将动态对象交接给其他智能指针


swap操作

有非成员函数和成员函数两个版本

1swap(p1, p2);
2p1.swap(p2);

智能指针


smart pointer

模板类: 创建智能指针时, 需提供所指对象的类型

提供机制管理动态对象, 在满足条件的情况下自动销毁其所管理的动态对象

智能指针
shared_ptr 允许多个shared_ptr共同管理同一个动态对象
unique_ptr 独占管理的动态对象
weak_ptr 伴随指针; 弱引用; 可以通过weak_ptr访问share_ptr管理的动态对象, 较内置指针更安全

头文件

1#include <memory>

shared_ptr和unique_ptr的共同操作


创建智能指针


创建空指针

未指向任何动态对象

1shared_ptr<T> sp;
2unique_ptr<T> up;
  • 示例

    1shared_ptr<string> sp1;
    2shared_ptr<list<int>> sp2;
    3
    4unique_ptr<double> up1;
    5unique_ptr<string> up2;

使用内置指针初始化智能指针

内置指针到智能指针是显式转换

  • 使用new运算符为智能指针申请动态内存

    存在一次转换: 内置指针转换为智能指针

    1. new运算符返回指向动态对象的内置指针
    2. 内置指针到智能指针的转换构造函数是explicit的
    1shared_ptr<T> sp(new T(args));
    2unique_ptr<T> up(new T(args));
    • 内置指针到智能指针的转换构造函数是explicit的

      1shared_ptr<T> sp = new T(args); // 错误
      2unique_ptr<T> up = new T(args); // 错误
      
      1shared_ptr<T> sp = shared_ptr<T>(new T(args)); // 正确
      2unique_ptr<T> up = unique_ptr<T>(new T(args)); // 正确
      
    • 示例: 使用new运算符返回的内置指针初始化智能指针

      1shared_ptr<int> p1(new int(10));
      2shared_ptr<int> p2 = shared_ptr<int>(new int(20));
      3
      4unique_ptr<int> p3(new int(42));
      5unique_ptr<string> p4(new string("Stegosaurus"));
      6unique_ptr<int> p5 = unique_ptr<int>(new int(10));
  • 内置指针将动态对象托管给智能指针

    托管后, 建议将内置指针置空

     1auto p1 = new T(args);
     2auto p2 = new T(args);
     3auto p3 = new T(args);
     4auto p4 = new T(args);
     5
     6shared_ptr<T> sp1(p1);
     7unique_ptr<T> up1(p2);
     8
     9shared_ptr<T> sp2 = shared_ptr<T>(p3);
    10unique_ptr<T> up2 = unique_ptr<T>(p4);
    11
    12p1 = p2 = p3 = p4 = nullptr;

解引用智能指针

*

要求智能指针非空

获取所指对象的引用

1*p;
  • 示例

    1shared_ptr<string> p1(new string);
    2if (p1 && p1->empty())
    3    *pi = "hi";
    4
    5// 首先是p1不为空,其次要求其指向一个空串
    

从内置指针接管动态对象

1auto p5 = new T(args);
2auto p6 = new T(args);
3
4sp1 = shared_ptr<T>(p5);
5up1 = unique_ptr<T>(p6);
6
7p5 = p6 = nullptr;

访问动态对象

  1. p指向是否为空

  2. 获取对象的引用

    不要解引用一个空指针

  3. 访问对象成员

1p;
2*p;
3p->mem;

示例

1shared_ptr<string> sp(new string);
2
3if (sp && sp->empty())
4{
5    *sp = "hi";
6}
7cout << *sp << endl;

get成员函数: 获取指向动态对象的内置指针

返回一个内置指针,指向智能指针管理的动态对象

实为智能指针到内置指针的转换

1T *pt = p.get();

通过内置指针使用动态对象期间,需要保证动态对象不被销毁

  1. 将管理动态对象的唯一一个shared_ptr置空, 触发动态对象销毁

    1shared_ptr<string> sp(new string("hello"));
    2string *ps = sp.get();
    3cout << *ps << endl;
    4sp = nullptr;     // 动态对象被销毁
    5string s = *ps;   // 错误: 访问非法内存
    6cout << s << endl;
  2. 管理动态对象的唯一一个shared_ptr在块结束时被销毁, 触发动态对象销毁

    sp和sp2的计数器不共用; 二者均以为自己是管理动态对象的唯一一个shared_ptr

    1shared_ptr<string> sp(new string("hello"));
    2string *p = sp.get();
    3cout << *p << endl;
    4{
    5    shared_ptr<string> sp2(p);
    6}                 // 动态对象被销毁
    7string foo = *sp; // 错误: 访问非法内存
    8cout << foo << endl;

通过内置指针访问动态对象时, 不能对该指针执行delete操作,更不能将动态对象交接给其他智能指针


swap操作

有非成员函数和成员函数两个版本

1swap(p1, p2);
2p1.swap(p2);