智能指针的概念

c++11标准和boost都提供了智能指针的功能。智能指针是普通指针的封装,智能指针是一个对象,对象里面包含了原生指针。可以使用智能指针对象的get()方法可获得封装在里面的原生指针。使用智能指针管理内存,用到智能指针的地方需要统一使用c++11或boost库,切忌混合使用。c++11的智能指针包含在<memory>库,boost库是<boost/smart_ptr>,使用时前者加前缀std::,后者加前缀boost::。在有的智能指针的类里,实现了operator*()和operator->()的操作符重载,这样的智能指针能够像普通指针一样使用直接*和->访问原生指针所指向的对象。

shared_ptr的知识点

最常用到的智能指针是shared_ptr,是对auto_ptr(已弃用)和unique_ptr的改进。

shared_ptr是引用计数型指针,所以它以前曾有名字count_ptr。

当拷贝一个对象时(比如调用拷贝构造函数、调用赋值函数、作为函数参数传递(会在函数内部拷贝一个临时对象,当退出函数时,析构该对象))引用计数加1;

当调用析构函数和reset()重置函数时,引用计数减1。

当引用计数为0时,会释放该对象里的指针(delete)。

由于shared_ptr的构造函数中是使用new申请内存,所以不能应用于使用new[]分配内存的场景。

enable_shared_from_this和shared_form_this

在对象的函数参数中,如果需要传递该对象this指针,可以将该对象所在类继承自enable_shared_form_this<T>,使用该类的shared_from_this()函数会返回一个封装了this指针的shared_ptr<T>对象。这种使用场景在,异步调用过程中,不知道何时调用回调函数,而该回调函数里需要使用到this对象。这就保证了无论何时调用回调函数u,this对象都一直存在且有效。

shared_ptr的调试

shared_ptr提供了use_count()、unique()方法进行调试。use_count()返回此时该对象封装的指针的的引用计数,unique()测试当前是否唯一,效率比use_count = 0高。此外,还可以使用断言函数assert()判断当前对象是否为真(不为空)。assert()包含在头文件<assert.h>中,出于效率考虑,一般用于debug版本。

实例

 /*
*例子主要功能:
*1.测试引用计数的增减
*2.shared_from_this的使用
*/
#include<iostream>
#include<assert.h>
#include<vector>
#include<memory>
using namespace std;
void TestCount(shared_ptr<int>);
typedef vector<shared_ptr<int> > VS;
class self_shared:public enable_shared_from_this<self_shared>
{
public:
self_shared(int n):x(n){}
int x;
void print()
{
cout<<"self_shared: "<<x<<endl;
} };
int main()
{
shared_ptr<int> p(new int());
cout<<"*p = "<<*p<<endl;
cout<<"use_count = "<<p.use_count()<<endl;
shared_ptr<int> q(p);
cout<<"use_count = "<<p.use_count()<<endl;
shared_ptr<int> pp = q;
cout<<"q.use_count() = "<<q.use_count()<<endl;
cout<<"pp.use_count() = "<<pp.use_count()<<endl;
p.reset();
assert(pp);
cout<<"pp.use_cout() = "<<pp.use_count()<<endl;
if(!pp.unique())
{
cout<<"I am not the unique\n";
}
cout<<*pp<<endl;
cout<<"before TestCount, pp.use_count = "<<pp.use_count()<<endl;
TestCount(pp);
cout<<"after TestCount, pp.use_count = "<<pp.use_count()<<endl;
VS vs();
int i = ;
for(auto pos = vs.begin(); pos != vs.end(); ++pos)
{
(*pos) = make_shared<int>(++i);
cout<<*(*pos)<<", ";
}
cout<<endl;
shared_ptr<int> ppp = vs[];
*ppp = ;
cout<<" *vs[9] = "<<*vs[]<<endl;
cout<<" vs[9].get() = "<<vs[].get()<<endl;
cout<<" *vs[9].get() = "<<*(vs[].get())<<endl;
auto sp = make_shared<self_shared>();
sp->print();
cout<<"sp.use_count() = "<<sp.use_count()<<endl;
auto spp = sp->shared_from_this();
spp->x = ;
spp->print();
sp->print();
cout<<"sp.use_count() = "<<sp.use_count()<<endl;
cout<<"spp.use_count() = "<<spp.use_count()<<endl;
return ;
}
void TestCount(shared_ptr<int> p)
{
shared_ptr<int> q = p;
cout<<"in the TestCount, q.use_count = "<<q.use_count()<<endl;
}

编译后运行,输出结果如下:

smart_ptr之shared_ptr的更多相关文章

  1. boost--smart_ptr库

    C++没有类似Java.C#等语言的垃圾回收机制,内存管理是最为头痛的工作. new.delete以及指针的不恰当运用是C++中造成资源获取/释放问题的根源. 智能指针是解决这些问题的一种方案,boo ...

  2. [boost] : lightweight_test库

    lightweight_test轻量级单元测试框架, 只支持最基本的单元测试, 不支持测试用例, 测试套件的概念, 简单小巧, 适合要求不高或者快速测试的工作. 基本用法 需要包含头文件#includ ...

  3. 为什么API多用C而不是C++,为什么C++程序大多不使用异常

    读Defective C++随笔 不尽知用兵之害者,则不能尽知用兵之利也 ——<孙子兵法> 1.为什么API多用C而不是C++以前就一直很奇怪,为什么API大都用C的方式提供,即使有C++ ...

  4. c++ shared_ptr 使用注意事项. 1

    条款1:不要把一个原生指针给多个shared_ptr管理 int* ptr = new int; shared_ptr<int> p1(ptr); shared_ptr<int> ...

  5. 记录以下boost::shared_ptr的一个使用细节

    shared_ptr<T>::operator->返回的是T*类型指针,非const T*指针.因此通过const shared_ptr<T>&类型的ptr可以直 ...

  6. 学习笔记:shared_ptr陷阱

    条款1:不要把一个原生指针给多个shared_ptr管理 int* ptr = new int; shared_ptr<int> p1(ptr); shared_ptr<int> ...

  7. Boost使用笔记(Smart_ptr)

    我是Word写的,复制过来实在懒得在排版了,有兴趣的朋友可以去我的百度文库看,谢谢 http://wenku.baidu.com/view/34e485e2f61fb7360b4c653e.html ...

  8. shared_ptr智能指针源码剖析

    (shared_ptr)的引用计数本身是安全且无锁的,但对象的读写则不是,因为 shared_ptr 有两个数据成员,读写操作不能原子化.根据文档 (http://www.boost.org/doc/ ...

  9. Boost源代码学习---shared_ptr.hpp

    最近观看Boost库源代码.Boost功能强大的库,但它的许多源代码,十一细读太费时间,毕竟,还有其他东西要学.所以我决定脱脂感兴趣的章节,他们的设计思路和难以理解的地方记录. shared_ptr是 ...

随机推荐

  1. Python3之切片及内置切片函数slice

       切片   取一个list或tuple的部分元素是非常常见的操作.比如,一个list L=[0,1,2,3,4,5,6,7,8,9] 取前3个元素,应该怎么做 笨方法,一个个列出来 >> ...

  2. 15.Git四种协议-本地协议(local)、HTTP协议、SSH协议、Git协议

    1.本地协议(loacl) 最基本的协议,其远程仓库其实就是硬盘内部的一个目录(例如D:\\project).常见于团队内的人对一个共享的文件系统(例如NFS)具有访问权限,或者多人共用一台电脑的情况 ...

  3. 【MM系列】SAP 采购订单收货后不能修改价格的增强

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP 采购订单收货后不能修改价格的 ...

  4. 安卓计数器类APP推荐

    1. Thing Counter - Google Play 上的应用 可添加多个计数器,同一页面展示,一行一个,操作直观方便: 可以更改计数器颜色,使页面更美观. 每个计数器有详情和历史记录 详情: ...

  5. kolla安装Queens版本OpenStack(ceph后端)

    OpenStack all-in-one部署: 本次部署为OpenStack Queens版本部署,使用All-in-one,单节点部署. 物理资源:8核,32GB,硬盘400GB(3个盘),2网卡. ...

  6. PS复制图层快捷键

    选中图层,按“Ctrl + J”即可快速复制图层.

  7. Jetbrains系列产品2019.2.3最新激活方法

    Jetbrains系列产品2019.2.3最新激活方法[持续更新] 发表于 2018-08-25 | 分类于 软件调试 本站惯例:本文假定你知道Jetbrains家的产品.不知道可以问问搜索引擎. 大 ...

  8. python并发编程之协程(实践篇)

    一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 对于单线程下,我们不可避免程序中出现io操作,但如果我们 ...

  9. set object is not JSON serializable 解决方式

    python return json的时候报错: set object is not JSON serializable 解决方式,增加一个将set转为list的函数: def set_default ...

  10. Redis慢日志取出来

    http://blog.chinaunix.net/uid-31396856-id-5758295.htmlhttps://blog.51cto.com/legehappy/2151986?sourc ...