zoukankan      html  css  js  c++  java
  • C++ 之 智能指针, 共享指针,独占指针,弱指针

    这篇博文对智能指针总结的很到位,感谢Neohope:

    Neohope's Blog) http://www.neohope.org/2018/08/15/%E6%B5%85%E8%B0%88cpp%E6%99%BA%E8%83%BD%E6%8C%87%E9%92%88/

    智能指针其实并不是指针,而是一个特殊对象。使用时需要包含头文件 #include<memory>
    在智能指针对象生命期即将结束时,它会调用析构函数释放有它管理的堆内存。
    访问智能指针管理对象的方法,使用操作符“->”(重载)。
    访问智能指针本来的方法,使用操作符“.”。

    我们常见的智能指针有以下几种:

    C98
    std::auto_ptr
    第一代智能指针,有些操作比如“=”坑比较多,不推荐使用。
    
    C11
    std::unique_ptr
    独占对象,并保证指针所指对象生命周期与其一致。
     
    std::shared_ptr
    可共享指针对象,可以赋值给shared_ptr或weak_ptr。
    通过引用计数的方式控制生命周期,当指针所指对象的所有的shared_ptr生命周期结束时(引用计数为0时)会被销毁。
     
    std::weak_ptr
    可以指向shared_ptr,但并不影响引用计数。
    不影像所指对象的生命周期,在引用所指对象时,先用需要lock()才能使用。
     
    Boost
    不共享对象,类似于std::unique_ptr
    boost::scoped_ptr
    boost::scoped_array
     
    共享对象,类似于std::shared_ptr
    boost::shared_ptr
    boost::shared_array
     
    共享对象,但不改变对象引用计数,类似于std::weak_ptr
    boost::weak_ptr
     
    侵入式引用计数,要求使用对象自己实现计数功能
    boost::intrusive_ptr

    下面是一个代码示例

      1 class MyTest
      2 {
      3 public:
      4     MyTest(string name, int age) {
      5         _name = name;
      6         _age = age;
      7     };
      8     ~MyTest()=default;
      9     void sayHello() {
     10         cout << "Hello " << _name << "! You are " << _age << " years old." << endl;
     11     };
     12 
     13 public:
     14     string _name;
     15     int _age;
     16 };
     17 
     18 
     19 void test_auto_ptr()
     20 {
     21     std::auto_ptr<MyTest> auto_ptr_01(new MyTest("tom", 20));
     22 
     23     if (auto_ptr_01.get())
     24     {
     25         auto_ptr_01->sayHello();
     26         auto_ptr_01.get()->_name = "jerry";
     27         auto_ptr_01->sayHello();
     28         (*auto_ptr_01)._age += 1;
     29         auto_ptr_01->sayHello();
     30     }
     31 
     32     //auto_ptr_02会抢占auto_ptr_01的对象
     33     //此后auto_ptr_01不指向MyTest对象
     34     std::auto_ptr<MyTest> auto_ptr_02 = auto_ptr_01;
     35     if (auto_ptr_01.get())
     36     {
     37         cout << "auto_ptr_01 is released" << endl;
     38     }
     39     auto_ptr_02->sayHello();
     40 
     41     //只是释放所有权,并不释放内存
     42     //MyTest* test = auto_ptr_02.release();
     43 
     44     //释放内存
     45     auto_ptr_02.reset();
     46     if (!auto_ptr_01.get())
     47     {
     48         cout << "auto_ptr_02 is released" << endl;
     49     }
     50 
     51 }
     52 
     53 void test_unique_ptr()
     54 {
     55     //独占对象
     56     //保证指针所指对象生命周期与其一致
     57     unique_ptr<MyTest> unique_ptr_01(new MyTest("tom", 20));
     58     unique_ptr_01->sayHello();
     59 
     60     //不允许直接做右值
     61     //unique_ptr<int> unique_ptr_02 = unique_ptr_01;
     62 
     63     //需要通过move来处理
     64     unique_ptr<MyTest> unique_ptr_03 = move(unique_ptr_01);
     65     if (!unique_ptr_01)cout << "unique_ptr_01 is empty" << endl;
     66     unique_ptr_03->sayHello();
     67 
     68     //释放指针
     69     unique_ptr_03.reset();
     70     if (!unique_ptr_03)cout << "unique_ptr_03 is empty" << endl;
     71 }
     72 
     73 void test_shared_ptr()
     74 {
     75     shared_ptr<MyTest> shared_ptr_01(make_shared<MyTest>("tom", 20));
     76     shared_ptr<MyTest> shared_ptr_02 = shared_ptr_01;
     77     shared_ptr_01->sayHello();
     78     shared_ptr_02->sayHello();
     79 
     80     shared_ptr_01.reset();
     81     if (!shared_ptr_01)cout << "shared_ptr_01 is empty" << endl;
     82     shared_ptr_02->sayHello();
     83 
     84     shared_ptr_02.reset();
     85     if (!shared_ptr_02)cout << "shared_ptr_02 is empty" << endl;
     86 }
     87 
     88 void test_weak_ptr()
     89 {
     90     shared_ptr<MyTest> shared_ptr_01(make_shared<MyTest>("tom", 20));
     91     weak_ptr<MyTest> weak_ptr_01 = shared_ptr_01;
     92     shared_ptr_01->sayHello();
     93     weak_ptr_01.lock()->sayHello();
     94 
     95     weak_ptr_01.reset();
     96     if (!weak_ptr_01.lock())cout << "weak_ptr_01 is empty" << endl;
     97     shared_ptr_01->sayHello();
     98 
     99     weak_ptr<MyTest> weak_ptr_02 = shared_ptr_01;
    100     weak_ptr<MyTest> weak_ptr_03 = weak_ptr_02;
    101     if (weak_ptr_01.lock())weak_ptr_02.lock()->sayHello();
    102     shared_ptr_01.reset();
    103     if (!weak_ptr_01.lock())cout << "weak_ptr_02 is empty" << endl;
    104 }
    105 
    106 int _tmain()
    107 {
    108     //test_auto_ptr();
    109     test_unique_ptr();
    110     test_shared_ptr();
    111     test_weak_ptr();
    112 
    113     return 0;
    114 }
  • 相关阅读:
    使用JSON.NET实现对象属性的格式化的自定义
    AspNetCore项目-Service注入或覆盖
    发布Nuget
    收藏
    工具
    快捷键大全
    SqlServer分页查询语句
    面试相关
    Eratosthes algrithm 求素数
    code training
  • 原文地址:https://www.cnblogs.com/cofludy/p/14678696.html
Copyright © 2011-2022 走看看