// 智能指针会自动释放所指向的对象。
// 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的更多相关文章
-
c/c++ 智能指针 shared_ptr 和 new结合使用
智能指针 shared_ptr 和 new结合使用 用make_shared函数初始化shared_ptr是最推荐的,但有的时候还是需要用new关键字来初始化shared_ptr. 一,先来个表格,唠 ...
-
c/c++ 智能指针 shared_ptr 使用
智能指针 shared_ptr 使用 上一篇智能指针是啥玩意,介绍了什么是智能指针. 这一篇简单说说如何使用智能指针. 一,智能指针分3类:今天只唠唠shared_ptr shared_ptr uni ...
-
C++智能指针shared_ptr
shared_ptr 这里有一个你在标准库中找不到的—引用数智能指针.大部分人都应当有过使用智能指针的经历,并且已经有很多关于引用数的文章.最重要的一个细节是引用数是如何被执行的—插入,意思是说你将引 ...
-
STL源码剖析-智能指针shared_ptr源码
目录一. 引言二. 代码实现 2.1 模拟实现shared_ptr2.2 测试用例三. 潜在问题分析 你可能还需要了解模拟实现C++标准库中的auto_ptr一. 引言与auto_ptr大同小异,sh ...
-
智能指针shared_ptr的用法
为了解决C++内存泄漏的问题,C++11引入了智能指针(Smart Pointer). 智能指针的原理是,接受一个申请好的内存地址,构造一个保存在栈上的智能指针对象,当程序退出栈的作用域范围后,由于栈 ...
-
智能指针 shared_ptr 解析
近期正在进行<Effective C++>的第二遍阅读,书里面多个条款涉及到了shared_ptr智能指针,介绍的太分散,学习起来麻烦.写篇blog整理一下. LinJM @HQU s ...
-
智能指针shared_ptr新特性shared_from_this及weak_ptr
enable_shared_from_this是一个模板类,定义于头文件<memory>,其原型为: template< class T > class enable_shar ...
-
C++ 智能指针 shared_ptr
今天晚上去旁听了C++高级编程的课,其中提到智能指针.第一反映还以为是auto_ptr呢,一听才知道是share_ptr这个.哦,原来是C++11特性.大致的原因是auto_ptr有一点缺陷,而sha ...
-
标准库中的智能指针shared_ptr
智能指针的出现是为了能够更加方便的解决动态内存的管理问题.注:曾经记得有本书上说可以通过vector来实现动态分配的内存的自动管理,但是经过试验,在gcc4.8.5下是不行的.这个是容易理解的,vec ...
随机推荐
-
JAVA 多线程随笔 (二) sleep, yield, join, wait 和notify
这里先说明一下锁对象,如果一个类比如Person里的方法都有synchronized来修饰,那么每一个方法的锁对象就是Person的一个实例person. 锁对象也可以针对某个特定的实例, 比如syn ...
-
BZOJ 2049: [Sdoi2008]Cave 洞穴勘測 LCT
入门级LCT: 仅仅有 Cut Link 2049: [Sdoi2008]Cave 洞穴勘測 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 3073 ...
-
BZOJ 1093 [ZJOI2007]最大半连通子图
1093: [ZJOI2007]最大半连通子图 Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1986 Solved: 802[Submit][St ...
-
groovy构建和解析xml文件
原文链接:http://www.ibm.com/developerworks/cn/java/j-pg05199/ 代码示例: 构建xml文件: def static createXmlFile(){ ...
-
Bayesian Formulation on Cooperative Tracking
Suppose a joint state representing a set of \(N_{n}\) nodes moving in a field\[ \textbf{X}= \b ...
-
postgresql 53300错误
1.查看当前库的最大连接数 show max_connections; 2.查看当前数据库的活动连接数 select datname,application_name,pid,state from p ...
-
查看和修改Linux服务器的时区和时间
一.查看和修改Linux的时区1. 查看当前时区 命令 : "date -R" 2. 修改设置Linux服务器时区方法 A 命令 : "tzselect" 方法 ...
-
hiho1259 A Math Problem (数位dp)
题目链接:http://hihocoder.com/problemset/problem/1259 题目大意:g(t)=(f(i)%k=t)的f(i)的个数 求所有的(0-k-1)的g(i)的异或总值 ...
-
CC攻击原理及防范方法
一. CC攻击的原理: CC攻击的原理就是攻击者控制某些主机不停地发大量数据包给对方服务器造成服务器资源耗尽,一直到宕机崩溃.CC主要是用来消耗服务器资源的,每个人都有这样的体验:当一个网页访问的人数 ...
-
JavaWeb——tomcat manager 403 Access Denied .You are not authorized to view this page.
403 Access Denied You are not authorized to view this page. If you have already configured the Manag ...