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 }

 

上一篇:shared_ptr的线程安全


下一篇:ORACLE内核参数