博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
智能指针shared_ptr
阅读量:6004 次
发布时间:2019-06-20

本文共 2961 字,大约阅读时间需要 9 分钟。

// 智能指针会自动释放所指向的对象。// shared_ptr的应用场景是:程序需要在多个对象间共享数据/* 先从应用场景入手吧,说矿工A发现了一个金矿。 * 然后矿工A喊来了矿工B,一起开采,不久后矿工A劳累过度死了。 * 矿工B继续开采着矿工A发现的金矿。 * 但是矿工B不久后得了尘肺病。 * 这时候如果矿工B喊来了矿工C,那矿工C就继续开采这个金矿, * 如果矿工B至死都没有喊anyone,那么这个金矿不再被任何人发现。 * * 我们来说说实现 * 每个矿工new一个对象,金矿new一个对象。 * 矿工死了就delte掉,金矿不再被发现也delte掉。 * * 但是我们有没有可能让最后一个矿工死时,金矿被自动delte掉? * 这样的话我们就不需要额外管理金矿对象了。 * 有可能啊,你用共享指针啊。 * 共享指针管理一个对象,管理一个引用计数。 * 每次对共享指针赋值和拷贝时,引用计数就加1。 * 当共享指针被销毁时,引用计数就减1。 * 这样就变成多个矿工间共享金矿数据了。 * * 下面我们来说说引用计数递增的情况 * 1 用一个shared_ptr初始化另一个shared_ptr,肯定调用拷贝构造函数喽 * 2 用一个shared_ptr赋值另一个shared_ptr,肯定调用赋值函数喽 * 3 将shared_ptr作为参数传递给一个函数,这个也会调用拷贝构造函数 * 4 将shared_ptr作为函数的返回值,这个也会调用拷贝构造函数 * * 下面我们来说说引用计数递减的情况 * 1 shared_ptr被销毁,参数出栈是被销毁的一种情况 * 2 给shared_ptr重新赋值 * * 一旦一个shared_ptr的引用计数变为0,它就会自动释放所管理的对象。 */#include 
#include
using namespace std;struct Gold{ ~Gold() {total = -1;} int total{20}; Gold &operator--() { --total; return *this; } const Gold operator--(int) { Gold tmp = *this; --(*this); return Gold(tmp); }};class Miner{public: Miner() : gold(make_shared
()) {} Miner(const Miner &miner) { gold = miner.gold; } void dig() { (*gold)--; } Gold *base() { return gold.get(); }private: shared_ptr
gold;};int main(int argc, char *argv[]){ auto miner1 = new Miner; auto miner2 = new Miner(*miner1); // 代码执行到这里 // @表示地址 usecount是引用计数 // miner1的gold @0x605f40 // miner2的gold @0x605f40 // shared_ptr的usecount是2 // 可见miner1和miner2的gold指向同一个对象 // 引用计数正确 auto gold = miner2->base(); // 代码执行到这里 // gold @0x605f40 miner1->dig(); cout << gold->total << endl; miner2->dig(); cout << gold->total << endl; miner1->dig(); cout << gold->total << endl; delete miner1; // 代码执行到这里 // miner1的gold (null) // miner2的gold @0x605f40 // shared_ptr的usecount是1 // 引用计数正确 miner2->dig(); cout << gold->total << endl; delete miner2; // 代码执行到这里 // miner1的gold (null) // miner2的gold @0x605f20 // miner2管理的对象(@0x605f40) 已被销毁 // 调用了Gold的析构函数 // gold->totle值为-1 // 至于miner2的gold @0x605f20 ?? // 管它呢,反正已引用不到 cout << gold->total << endl; int *p2; { auto p1 = make_shared
(5); p2 = p1.get(); // 代码执行到这里 // p1 @0x605f60 // usecount是1 // p2 指向@0x605f60 } // 代码执行到这里 // 代码块出栈了,p1被销毁 // usecount变为0,所以p1管理的对象也被销毁了 // ***这是为什么不建议用get的原因 // 虽然可以正确输出p2所指向的对象,但是这是不确定的 // p2就是所谓的野指针了 cout << *p2 << endl; shared_ptr
p4; { auto p3 = make_shared
(5); p4 = p3; // 代码执行到这里 // p3 @0x605f60 // p4 @0x605f60 // usecount是2 } // 代码执行到这里 // 代码块出栈了,p3被销毁 // usecount变为1,p3并未销毁所管理的对象 // p4所管理的对象可以正确输出 cout << *p4 << endl; return 0;}

转载于:https://www.cnblogs.com/the-capricornus/p/6383466.html

你可能感兴趣的文章
Nginx下载服务生产服务器调优
查看>>
RHEL6.5_KVM_VLAN_SET
查看>>
Windows下GCC编译环境中文乱码解决方案
查看>>
linux cut
查看>>
Linux 下JDK 安装
查看>>
DNS详解之重新认识DNS一
查看>>
VC中绘图练习(第三方库)
查看>>
MySql增加用户、授权、修改密码等语句
查看>>
xmlPullParser
查看>>
突破边缘,Know yourself!
查看>>
常见http状态码
查看>>
ldap 安装
查看>>
我的友情链接
查看>>
使用secure CRT的SFTP在LINUX与WINDOWS下交换文件
查看>>
Docker单独设置代理服务
查看>>
移动互联网,入口生死战
查看>>
nginx面试常问题目
查看>>
制作ubuntu系统u盘镜像,以及安装
查看>>
swift3.0layer折叠 淘宝商品View折叠
查看>>
Git忽略文件配置
查看>>