智能指针-1
引用计数是智能指针的一种通用实现技术,基本原理如下:
- 在每次创建类的新对象时,初始化指针并将引用计数置 1;
- 当对象作为另一对象的副本而创建时(复制构造函数),复制对应的指针并将引用计数 +1;
- 当对一个对象进行赋值时,赋值操作符 = 将左操作数所指对象的引用计数 -1,将右操作数所指对象的引用计数 +1;
- 调用析构函数数,引用计数 -1;
- 上述操作中,引用计数减至 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 }