经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
C语言?智能指针?shared_ptr?和?weak_ptr
来源:jb51  时间:2022/4/11 20:16:12  对本文有异议

weak_ptr引入可以解决shared_ptr交叉引用时无法释放资源的问题。

示例代码:

  1. #include <iostream>
  2. #include <memory>
  3.  
  4. using namespace std;
  5.  
  6. class B;
  7.  
  8. class A{
  9. public:
  10. ? ? A(){cout << "A constructor ... "<< endl;}
  11. ? ? ~A(){cout << "A destructor ..." << endl;}
  12. ? ? std::shared_ptr<B> pb;
  13. };
  14.  
  15. class B{
  16. public:
  17. ? ? B(){cout << "B constructor ... "<< endl;}
  18. ? ? ~B(){cout << "B destructor ..." << endl;}
  19. ? ? std::shared_ptr<A> pa;
  20. };
  21.  
  22. int main(int argc, char **argv) {
  23. ? ??
  24. ? ? std::shared_ptr<int> a = std::make_shared<int>(3);
  25. ? ? std::shared_ptr<char> b = std::make_shared<char>('a');
  26. ? ??
  27. ? ? std::cout << "shared_ptr object(int) size = " << sizeof(a) << std::endl;
  28. ? ? std::cout << "shared_ptr object(char) size = " << sizeof(b) << std::endl;
  29. ? ??
  30. ? ? std::weak_ptr<A> shadow_a;
  31. ? ? std::weak_ptr<B> shadow_b;
  32. ? ??
  33. ? ? {
  34. ? ? std::shared_ptr<A> ptr_a = std::make_shared<A>();
  35. ? ? std::shared_ptr<B> ptr_b = std::make_shared<B>();
  36. ? ??
  37. ? ? shadow_a = ptr_a;
  38. ? ? shadow_b = ptr_b;
  39. ? ??
  40. ? ? ptr_a->pb = ptr_b;
  41. ? ? ptr_b->pa = ptr_a;
  42. ? ??
  43. ? ? cout << "reference count of A = " << shadow_a.use_count() << endl;
  44. ? ? cout << "reference count of B = " << shadow_b.use_count() << endl;
  45. ? ? cout << endl;?
  46. ? ? }
  47. ? ??
  48. ? ? cout << "reference count of A = " << shadow_a.use_count() << endl;
  49. ? ? cout << "reference count of B = " << shadow_b.use_count() << endl;
  50. ? ??
  51. ? ? std::cout << "Hello, world!" << std::endl;
  52. ? ? return 0;
  53. }

运行代码得到以下输出:

shared_ptr object(int) size = 16
shared_ptr object(char) size = 16
A constructor ... 
B constructor ... 
reference count of A = 2
reference count of B = 2

reference count of A = 1
reference count of B = 1
Hello, world!

从结果可以看出,由于交叉引用导致申请的内存A,B无法正常释放。
为什么会这样呢?这个应该从析构原理进行考虑,shared_ptr引用计数需要为0才会进行析构!但是ptr_a离开作用域会导致A引用计数减少1,但是A的引用计数此时为1,那么 pb不会释放;同理,ptr_b离开作用域会导致B引用计数减少1,但是B的引用计数为此时为1,那么pa不会释放。如此导致了资源无法释放掉。
由于weak_ptr并不会改变shared_ptr的引用计数,所以修改类A,和类B中的shared_ptr对象为weak_ptr对象即可释放资源。

修改后的代码如下:

  1. #include <iostream>
  2. #include <memory>
  3.  
  4. using namespace std;
  5.  
  6. class B;
  7.  
  8. class A{
  9. public:
  10. ? ? A(){cout << "A constructor ... "<< endl;}
  11. ? ? ~A(){cout << "A destructor ..." << endl;}
  12. ? ? //std::shared_ptr<B> pb;
  13. ? ? std::weak_ptr<B> pb;
  14. };
  15.  
  16. class B{
  17. public:
  18. ? ? B(){cout << "B constructor ... "<< endl;}
  19. ? ? ~B(){cout << "B destructor ..." << endl;}
  20. ? ? //std::shared_ptr<A> pa;
  21. ? ? std::weak_ptr<A> pa;
  22. };
  23.  
  24. int main(int argc, char **argv) {
  25. ? ??
  26. ? ? std::shared_ptr<int> a = std::make_shared<int>(3);
  27. ? ? std::shared_ptr<char> b = std::make_shared<char>('a');
  28. ? ??
  29. ? ? std::cout << "shared_ptr object(int) size = " << sizeof(a) << std::endl;
  30. ? ? std::cout << "shared_ptr object(char) size = " << sizeof(b) << std::endl;
  31. ? ??
  32. ? ? std::weak_ptr<A> shadow_a;
  33. ? ? std::weak_ptr<B> shadow_b;
  34. ? ??
  35. ? ? {
  36. ? ? std::shared_ptr<A> ptr_a = std::make_shared<A>();
  37. ? ? std::shared_ptr<B> ptr_b = std::make_shared<B>();
  38. ? ??
  39. ? ? shadow_a = ptr_a;
  40. ? ? shadow_b = ptr_b;
  41. ? ??
  42. ? ? ptr_a->pb = ptr_b;
  43. ? ? ptr_b->pa = ptr_a;
  44. ? ??
  45. ? ? cout << "reference count of A = " << shadow_a.use_count() << endl;
  46. ? ? cout << "reference count of B = " << shadow_b.use_count() << endl;
  47. ? ? cout << endl;?
  48. ? ? }
  49. ? ??
  50. ? ? cout << "reference count of A = " << shadow_a.use_count() << endl;
  51. ? ? cout << "reference count of B = " << shadow_b.use_count() << endl;
  52. ? ??
  53. ? ? std::cout << "Hello, world!" << std::endl;
  54. ? ? return 0;
  55. }

运行结果如下,可以正常释放资源。

shared_ptr object(int) size = 16
shared_ptr object(char) size = 16
A constructor ... 
B constructor ... 
reference count of A = 1
reference count of B = 1

B destructor ...
A destructor ...
reference count of A = 0
reference count of B = 0
Hello, world!

到此这篇关于C语言 智能指针 shared_ptr 和 weak_ptr的文章就介绍到这了,更多相关 shared_ptr 和 weak_ptr内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号