一:shared_ptr
基本概念:
shared_ptr通过一个引用计数,共享一个对象,shared_ptr为了解决unique_ptr在对象所有权上的局限性,在使用引用计数的机制上提供了可以共享对象所有权的职能指针,当然这需要额外的开销。当引用计数为0时,该对象没有被使用,可以进行析构。

潜在问题:
引用计数会带来循环引用的问题,会导致堆里的内存无法被回收导致内存泄漏。
如下图所示:
如果某一时刻pA指针指向了B对象,而PB指针指向了对象A。如果想要释放A对象内存,A对象发现自己内部有指针指向B对象,所以需要先释放B对象,再释放A对象才能不会导致程序出错。而B对象也存在相同的问题,都需要先释放对方对象导致了循环引用,那么为了解决这个问题,我们引入了weak_ptr。

二:weak_ptr
基本概念:
weak_ptr被设计为与shared_ptr共同工作,用一种观察者模式工作。作用时协助shared_ptr工作,可获得资源的观测权,像旁观者那样观察资源的使用情况。观察者意味着weak_ptr只对shared_ptr进行引用,而不改变其引用计数,当被观察的shared_ptr失效后相应的weak_ptr也会失效。

下面看下shared_ptr的简单用例

#include <iostream>
#include <memory>
using namespace std;int main(int argc, const char * argv[])
{// insert code here...//shared_ptr:shared_ptr代表的是共享所有权,即多个shared_ptr可以共享一块内存auto wA = shared_ptr<int>(new int(20));{auto wA2 = wA;cout << ((wA2.get()!=nullptr)?(*wA2.get()):-1)<<endl; //20cout << ((wA.get()!=nullptr)?(*wA.get()):-1)<<endl; //20cout << wA2.use_count()<<endl;                      //2cout << wA2.use_count()<<endl;                      //2}cout << wA.use_count()<<endl;//move语法auto wAA = std::make_shared<int>(30);auto wAA2 = std::move(wAA); //此时wAA等于nullptr,wAA2.use_count()等于1cout<<((wAA.get()!=nullptr)?(*wAA.get()):-1)<<endl; //-1cout<<((wAA2.get()!=nullptr)?(*wAA2.get()):-1)<<endl; //30cout << wAA.use_count()<<endl;                       //0cout <<wAA2.use_count()<<endl;                       //1return 0;
}

下面看下针对于weak_ptr所做的观察工作用例

#include <iostream>
#include <memory>using namespace std;struct B;
struct A
{shared_ptr<B> pb;~A(){cout <<"~A()"<<endl;}
};struct B
{shared_ptr<A> pa;~B(){cout <<"~B()"<<endl;}
};//pa和pb存在着循环引用,根据shared_ptr引用计数的原理,pa和pb都无法被正常的释放。
//weak_ptr是为了解决shared_ptr双向引用的问题
struct BW;
struct AW
{shared_ptr<BW> pb;~AW(){cout <<"~AW()"<<endl;}
};struct BW
{weak_ptr<AW> pa;~BW(){cout <<"~BW()"<<endl;}
};void Test()
{cout <<"Test shared_ptr and shared_ptr"<<endl;shared_ptr<A> tA(new A());shared_ptr<B> tB(new B());cout <<tA.use_count()<<endl;      //1cout <<tB.use_count()<<endl;      //1tA->pb = tB;tB->pa = tA;cout <<tA.use_count()<<endl;      //2cout <<tB.use_count()<<endl;      //2
}void Test2()
{cout <<"Test shared_ptr and weak_ptr"<<endl;shared_ptr<AW> tA(new AW());shared_ptr<BW> tB(new BW());cout <<tA.use_count()<<endl;      //1cout <<tB.use_count()<<endl;      //1tA->pb = tB;tB->pa = tA;cout << tA.use_count()<<endl;     //1cout << tB.use_count()<<endl;     //2
}int main(int argc, const char * argv[])
{// insert code here...Test();Test2();return 0;
}

shared_ptr,weak_ptr使用最广范的智能指针相关推荐

  1. C++智能指针剖析(上)std::auto_ptr与boost::scoped_ptr

    1. 引入 C++语言中的动态内存分配没有自动回收机制,动态开辟的空间需要用户自己来维护,在出函数作用域或者程序正常退出前必须释放掉. 即程序员每次 new 出来的内存都要手动 delete,否则会造 ...

  2. 深入学习c++--智能指针(二) weak_ptr(打破shared_ptr循环引用)

    1. 几种智能指针 1. auto_ptr: c++11中推荐不使用他(放弃) 2. shared_ptr: 拥有共享对象所有权语义的智能指针 3. unique_ptr: 拥有独有对象所有权语义的智 ...

  3. C++11中的智能指针unique_ptr、shared_ptr和weak_ptr详解

    目录 1.引言 2.什么是智能指针? 3.在Visual Studio中查看智能指针的源码实现 4.独占式指针unique_ptr 4.1.查看unique_ptr的源码实现片段 4.2.为什么uni ...

  4. C++智能指针shared_ptr、unique_ptr以及weak_ptr

    目录 shared_ptr类 shared_ptr和unique_ptr都支持的操作 shared_ptr独有的操作 make_shared函数 shared_ptr自动销毁所管理的对象 由普通指针管 ...

  5. [C++11]弱引用智能指针weak_ptr初始化和相关的操作函数

    弱引用智能指针 std::weak_ptr 可以看做是 shared_ptr 的助手,它不管理 shared_ptr 内部的指针.std::weak_ptr 没有重载操作符 * 和 ->,因为它 ...

  6. 【C++11新特性】 C++11智能指针之shared_ptr

    http://blog.csdn.net/Xiejingfa/article/details/50750037 原创作品,转载请标明:http://blog.csdn.net/Xiejingfa/ar ...

  7. 智能指针的用法shared_ptr

    目录 智能指针 shared_ptr共享的智能指针 shared_ptr的基本用法 1.初始化 reset成员函数 make_shared swap()函数 2. 获取原始指针(get()) 3. 指 ...

  8. C++智能指针unique_ptr与shared_ptr

    文章目录 1.unique_ptr特点 2.unique_ptr例子 3.unique_ptr总结 4.shared_ptr特点 5.shared_ptr例子 6.shared_ptr中的自定义删除器 ...

  9. C++智能指针之shared_ptr

    C++智能指针之shared_ptr 前言 一.Shared_ptr 1.1 shared_ptr类的操作 1.2 make_shared函数 1.3 shared_ptr的拷贝赋值 1.4 shar ...

最新文章

  1. 前端开发学习Day27
  2. DFS遍历图时的小技巧
  3. ajax传formdata类型的数据_JQuery.Ajax()的data参数类型
  4. java batch批量
  5. Jmail的使用,可以发送给多人
  6. 推荐几款提升效率的神器
  7. 学物理好还是学计算机好,高考物理好适合学什么专业 物理好大学怎么选专业...
  8. Spring启动异常: cvc-elt.1: Cannot find the declaration of element 'beans'(转)
  9. bash不能运行c语言,解决:无法加载文件 C:\\Program Files\\.. 因为在此系统上禁止运行脚本。...
  10. StringRedisTemplate和RedisTemplate区别和联
  11. 全地形机器人HEXA评测:不做玩具 钻洞爬台阶可编程 | 评测
  12. BT.709 vs BT.2020
  13. 2022 阿里 java 面经
  14. 缓慢变化维解决方案——拉链表实现详解
  15. RSSI,RSRP,RSRQ and SINR
  16. 千峰java 笔记整理_JAVA学习笔记系列:菜鸟Vue学习笔记(四)
  17. 搜索引擎-xunsearch(讯搜)
  18. 若依框架添加静态页面,路由配置
  19. JAVA开发运维(Jenkins中踩的坑)
  20. dual_contrastive_loss粗略解读

热门文章

  1. Effective C++ 笔记(1)让自己习惯c++
  2. 优化一个奇葩表设计上的全表扫描SQL
  3. HttpContext.Current.Cache在控制台下不工作
  4. 【Hadoop代码笔记】Hadoop作业提交之客户端作业提交
  5. 如何不用MDI方式在Form1上显示Form2
  6. mysql中连接和断开数据库_robot framework——连接和断开mysql数据库
  7. python怎么设置颜色深浅变化_机器学习中减弱不同图像数据色调及颜色深浅差异...
  8. Python逐块执行另一个Python程序中的代码观察运行过程
  9. Python使用reduce()函数计算多个集合的并集与交集
  10. 饥荒显示服务器建立时遇到问题,饥荒显示创建服务器遇到问题重试 | 手游网游页游攻略大全...