这篇博文对智能指针总结的很到位,感谢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 }