智能指针-1


引用计数是智能指针的一种通用实现技术,基本原理如下:

  1. 在每次创建类的新对象时,初始化指针并将引用计数置 1;
  2. 当对象作为另一对象的副本而创建时(复制构造函数),复制对应的指针并将引用计数 +1;
  3. 当对一个对象进行赋值时,赋值操作符 = 将左操作数所指对象的引用计数 -1,将右操作数所指对象的引用计数 +1;
  4. 调用析构函数数,引用计数 -1;
  5. 上述操作中,引用计数减至 0 时,删除基础对象;

STL 库中的智能指针 shared_ptr 和 TARS 智能指针都使用了该引用计数原理,后面会进行介绍。


STL 库的智能指针
C++ 标准模板库 STL 中提供了四种指针 auto_ptr, unique_ptr, shared_ptr, weak_ptr。

auto_ptr 在 C++98 中提出,但其不能共享对象、不能管理数组指针,也不能放在容器中。因此在 C++11 中被摒弃,并提出 unique_ptr 来替代,支持管理数组指针,但不能共享对象。

shared_ptr 和 weak_ptr 则是 C++11 从标准库 Boost 中引入的两种智能指针。shared_ptr 用于解决多个指针共享一个对象的问题,但存在循环引用的问题,引入 weak_ptr 主要用于解决循环引用的问题。

接下来将详细介绍 shared_ptr


shared_ptr
shared_ptr 解决了在多个指针间共享对象所有权的问题,最初实现于 Boost 库中,后来收录于 C++11 中,成为了标准的一部分。shared_ptr 的用法如下
————————————————
版权声明:本文为CSDN博主「TARS基金会」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/TARSFoundation/article/details/109456189

 

 

简单介绍智能指针  shared_ptr 的用法

 

 1 #include <memory>
 2 #include <iostream>
 3 using namespace std;
 4 
 5 class A {
 6 public:
 7     A() {};
 8     ~A() {
 9         cout << "A is destroyed " << endl;
10     }
11 };
12 
13 class B {
14 public:
15     B() {
16         cout << "B is construct" << endl;
17     };
18     B(int b) {
19         cout << "B2 is construct" << endl;
20     }
21     ~B() {
22         cout << "B is destroyed " << endl;
23     }
24 };
25 
26 
27 int main()
28 {
29     //shared_ptr 引用技术打印
30     std::shared_ptr<A> sptrA(new A);
31     cout <<"sptrA count:"<< sptrA.use_count() << endl;
32     {
33         std::shared_ptr<A> cp_sptrA = sptrA;
34         cout << "sptrA count:" << sptrA.use_count() << endl;
35     }
36     cout << "sptrA count:" << sptrA.use_count() << endl;
37 
38 
39     //使用 make_shared 创建 shared_ptr对象
40     std::shared_ptr<B> sptrB1 = std::make_shared<B>();
41     std::shared_ptr<B> sptrB2 = std::make_shared<B>(2);
42 
43     system("pause");
44     return 0;
45 }

 

make_shared 用法,请参考其他相关文章。

https://www.cnblogs.com/zzm1/p/14077662.html

 

 

shared_ptr 循环引用问题举例:

 1 #include <memory>
 2 #include <iostream>
 3 using namespace std;
 4 
 5 class B;
 6 class A
 7 {
 8 public:
 9     A() : m_sptrB(nullptr) {};
10     ~A()
11     {
12         //循环引用,导致析构函数无法执行,内存不能释放
13         cout << " A is destroyed" << endl;
14     }
15     shared_ptr<B> m_sptrB;
16 };
17 
18 class B
19 {
20 public:
21     B() : m_sptrA(nullptr) {};
22     ~B()
23     {
24         //循环引用,导致析构函数无法执行,内存不能释放
25         cout << " B is destroyed" << endl;
26     }
27     shared_ptr<A> m_sptrA;
28 };
29 
30 int main()
31 {
32     {
33         shared_ptr<B> sptrB(new B);//sptrB对应的引用计数置为1
34         shared_ptr<A> sptrA(new A);//sptrA对应的引用计数置为1
35         sptrB->m_sptrA = sptrA;//sptrA对应的引用计数变成2,sptrB仍然是1
36         sptrA->m_sptrB = sptrB;//sptrB对应的引用计数变成2,sptrA是2
37     }
38     //退出main函数后,sptrA和sptrB对应的引用计数都-1,变成1,
39     //此时A和B的析构函数都不能执行(引用计数为0才能执行),无法释放内存
40     return 0;
41 }

 

posted @ 2021-12-03 14:02  He_LiangLiang  阅读(85)  评论(0编辑  收藏  举报