// 智能指针会自动释放所指向的对象。
// 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 <iostream>
#include <memory> 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<Gold>()) {} Miner(const Miner &miner)
{
gold = miner.gold;
} void dig()
{
(*gold)--;
} Gold *base()
{
return gold.get();
} private:
shared_ptr<Gold> 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<int>(5);
p2 = p1.get(); // 代码执行到这里
// p1 @0x605f60
// usecount是1
// p2 指向@0x605f60
} // 代码执行到这里
// 代码块出栈了,p1被销毁
// usecount变为0,所以p1管理的对象也被销毁了
// ***这是为什么不建议用get的原因
// 虽然可以正确输出p2所指向的对象,但是这是不确定的
// p2就是所谓的野指针了
cout << *p2 << endl; shared_ptr<int> p4;
{
auto p3 = make_shared<int>(5);
p4 = p3; // 代码执行到这里
// p3 @0x605f60
// p4 @0x605f60
// usecount是2
} // 代码执行到这里
// 代码块出栈了,p3被销毁
// usecount变为1,p3并未销毁所管理的对象
// p4所管理的对象可以正确输出
cout << *p4 << endl; return 0;
}

智能指针shared_ptr的更多相关文章

  1. c/c++ 智能指针 shared_ptr 和 new结合使用

    智能指针 shared_ptr 和 new结合使用 用make_shared函数初始化shared_ptr是最推荐的,但有的时候还是需要用new关键字来初始化shared_ptr. 一,先来个表格,唠 ...

  2. c/c++ 智能指针 shared_ptr 使用

    智能指针 shared_ptr 使用 上一篇智能指针是啥玩意,介绍了什么是智能指针. 这一篇简单说说如何使用智能指针. 一,智能指针分3类:今天只唠唠shared_ptr shared_ptr uni ...

  3. C++智能指针shared_ptr

    shared_ptr 这里有一个你在标准库中找不到的—引用数智能指针.大部分人都应当有过使用智能指针的经历,并且已经有很多关于引用数的文章.最重要的一个细节是引用数是如何被执行的—插入,意思是说你将引 ...

  4. STL源码剖析-智能指针shared_ptr源码

    目录一. 引言二. 代码实现 2.1 模拟实现shared_ptr2.2 测试用例三. 潜在问题分析 你可能还需要了解模拟实现C++标准库中的auto_ptr一. 引言与auto_ptr大同小异,sh ...

  5. 智能指针shared_ptr的用法

    为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...

  6. 智能指针 shared_ptr 解析

    近期正在进行<Effective C++>的第二遍阅读,书里面多个条款涉及到了shared_ptr智能指针,介绍的太分散,学习起来麻烦.写篇blog整理一下. LinJM   @HQU s ...

  7. 智能指针shared_ptr新特性shared_from_this及weak_ptr

    enable_shared_from_this是一个模板类,定义于头文件<memory>,其原型为: template< class T > class enable_shar ...

  8. C++ 智能指针 shared_ptr

    今天晚上去旁听了C++高级编程的课,其中提到智能指针.第一反映还以为是auto_ptr呢,一听才知道是share_ptr这个.哦,原来是C++11特性.大致的原因是auto_ptr有一点缺陷,而sha ...

  9. 标准库中的智能指针shared_ptr

    智能指针的出现是为了能够更加方便的解决动态内存的管理问题.注:曾经记得有本书上说可以通过vector来实现动态分配的内存的自动管理,但是经过试验,在gcc4.8.5下是不行的.这个是容易理解的,vec ...

随机推荐

  1. 基于Keepalvied的Mysql主主漂移(切换)

    Keepalived实现原理:Keepalived详细介绍简介 实验环境 Master1.Amoeba--IP:192.168.1.5 Master2---IP:192.168.1.10 同时安装ke ...

  2. (简单) POJ 3984 迷宫问题,BFS。

    Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, ...

  3. awk程序设计语言之-awk基础

    awk程序设计语言之-awk基础 http://man.linuxde.net/ 常用工具命令之awk命令 awk是一种编程语言,用于在Linux/Unix下对文本和数据处理.数据可以来自标准输入(s ...

  4. [cocos2d-x] --- CCNode类详解

    Email : awodefeng@163.com 1 CCNode是cocos2d-x中一个很重要的类,CCNode是场景.层.菜单.精灵等的父类.而我们在使用cocos2d-x时,接触最多的就是场 ...

  5. 统计学常用概念:T检验、F检验、卡方检验、P值、自由度

    1,T检验和F检验的由来 一般而言,为了确定从样本(sample)统计结果推论至总体时所犯错的概率,我们会利用统计学家所开发的一些统计方法,进行统计检定. 通过把所得到的统计检定值,与统计学家建立了一 ...

  6. UVa 10720 - Graph Construction

    题目大意:给n个整数, 分别代表图中n个顶点的度,判断是否能构成一张图. 看到这个题后,除了所有数之和应该为偶数之外,没有别的想法了,只好在网上搜解题报告了.然后了解了Havel-Hakimi定理.之 ...

  7. input 框上传多个文件

    在input标签中加入 multiple 属性,可以在一个输入框中选择多个文件进行上传 <input type="file" name="img" mul ...

  8. 基于arm开发板四个按键控制四个灯亮

    基于s5pv2410,cortex a8的四个按键每一个按键点了对应的灯 对于用汇编来编程的话不难,重点在于数据手册,电路图,管脚的看懂 直接上代码 .globl _start_start: ldr ...

  9. QT第六天学习

    基本事件: 鼠标事件 键盘事件 绘制事件 1.QT中的事件: 事件是对各应用程序需要知道的由应用程序内部或外部产生的事情或动作的通称. QT中事件的处理: 在QT中使用一个对象来表示一个事件,继承自Q ...

  10. 在Unity3D中实现安卓平台的本地通知推送

    [前言] 对于手游来说,什么时候需要推送呢?玩过一些带体力限制的游戏就会发现,我的体力在恢复满后,手机会收到一个通知告诉我体力已完全恢复了.这类通知通常是由本地的客户端发起的,没有经过服务端. 在安卓 ...