智能指针之shared_ptr基本概述
2024-10-07 01:24:52
1.shared_ptr允许有多个指针指向同一个对象,unique_ptr独占所指向的对象。
2.类似于vector,智能指针也是模板。创建智能指针:
shared_ptr<string> p1; //指向string的shared_ptr
shared_ptr<list<int>> p2; //指向int的list的shared_ptr
使用make_shared函数分配一个对象并初始化它,make_shared函数返回一个指向此对象的shared_ptr:
//指向值为42的int的shared_ptr
shared_ptr<int> p3 = make_shared<int>(); //指向一个值为“999”的string
shared_ptr<string> p4 = make_shared<string>(""); //指向一个值初始化的int,即值为0
shared_ptr<int> p5 = make_shared<int>();
3.我们可以认为每个share_ptr都有一个关联的计数器,通常称为引用计数(reference count)。无论何时我们拷贝一个shared_ptr,计数器都会递增。
例如这些都会使所关联的计数器递增:
(1)当用一个shared_ptr初始化另外一个shared_ptr
(2)将它作为参数传递给另外一个函数
(3)作为函数的返回值
例如这些操作会使计数器都会递减:
(1)给share_ptr赋新的值
(2)share_ptr被销毁
(3)局部的share_ptr离开作用域
以下通过两个例子来讲解计数的规则:
shared_ptr<int> p = make_shared<int>();
shared_ptr<int> q(p); //此对象现在有两个引用者,计数为2
shared_ptr<int> r = make_shared<int>(); //r现在有一个计数
r = q; //r现在指向q所指向的对象了,所以第二个42被销毁,因为计数为0
//而第一个计数为3
cout << "p所指对象的引用计数为:" << p.use_count() << endl;
再比如下一个程序:
shared_ptr<Foo> factory(T arg)
{
return make_shared<Foo>(arg); //返回一个shared_ptr<Foo>
}
void use_factory(T arg)
{
shared_ptr<Foo> p = factory(arg); //此时p的计数值为1
} //由于p是局部变量,出了这个函数,计数值先递减,然后检查计数值,发现为0,销毁p的对象,内存被释放掉
shared_ptr<Foo> use_factory(T arg)
{
shared_ptr<Foo> p = factory(arg); //此时p的计数值为1
return p; //返回了一个智能指针类,计数值加1,为2
} //离开了作用域,但是指向的内存不会被释放,因为还有对象的引用计数不是0
4.当指向的最后一个shared_ptr被销毁时,是调用析构函数来完成销毁工作的,析构函数会先递减它所指向的对象的引用计数,再检查引用计数值,如果引用计数变为0,那么shared_ptr析构函数就会销毁对象,并释放它占用的内存。
附:shared_ptr支持的一些操作:
最新文章
- 函数的caller属性
- Spring配置文件详解 - applicationContext.xml文件路径
- MFC中使用Duilib--2
- Annotation【转】
- c语言中3n+1溢出问题解决
- POJ2914
- BZOJ2213: [Poi2011]Difference
- 如何理解 css3 的 perspective 属性
- uiscrollview 事件冲突
- Specified key was too long; max key length is 767 b
- java jdk中安装证书的步骤
- Mac下nvm管理node.js版本问题
- python:Json模块dumps、loads、dump、load介绍
- db2常见错误代码及原因
- 依赖注入demo
- pyc文件是什么【转载】
- day11有参装饰器,无参装饰器
- 一个Zabbix agent配置多个Zabbix Server
- [转] javascript组件开发方式
- Intelli公司IDE快捷键设置
热门文章
- 小记---------sparkRDD的Transformation 和 Action 及案例 原理解释
- DFS搜索算法--(1)基础图遍历 绝对看!的!懂!
- P1828香甜的黄油
- liunx crontab 定时访问指定url
- java-阿里云发送短信
- Zookeeper报错Will not attempt to authenticate using SASL解决办法
- springboot(十六)-swagger2
- linux无界面模式安装selenium+chrome+chromedriver并成功完成脚本(亲测可用)
- hadoop的价值在哪里
- Ubuntu 18.04 LTS 64位Linux搭建Kubernetes 1.15.3并join子节点的完整过程