智能指针的概念

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;
}

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

最新文章

  1. StringBuffer 的 各种方法
  2. IntentService简介
  3. jQuery实例—选项卡(js源码和jQuery)【一些常见方法(1)-练习】
  4. python 数据字典应用
  5. 稀疏矩阵coo_matrix的乘法
  6. Embedded Linux Primer----嵌入式Linux基础教程--前言
  7. AST的作用
  8. 行为型---状态者模式(State Pattern)
  9. Ajax 调用的WCF
  10. JS中sort()方法原理及使用
  11. hive中sql使用英文分号
  12. ajax二次封装之异步加载
  13. Transparent Huge Pages
  14. Flash网页mp3播放器代码(3例)
  15. postgresql分区表探索(pg_pathman)
  16. u方法传参
  17. zookeeper单节点windows下安装
  18. WSDL(WebService描述语言)文件介绍
  19. msys git 安装配置、git命令行使用
  20. Java Native Interface Specification Contents 翻译

热门文章

  1. 讲不明白自杀系列:KMP算法
  2. c# 如何给 dataGridView里添加一个自增长列(列名为序号)
  3. 同时支持Android 和 ios 投屏到电脑的软件,Support Android and ios screen shrare to PC - 希沃授课助手
  4. 计数器+打卡+习惯+目标APP推荐
  5. 什么是挂载(mount)?
  6. PCL学习(五)如何在mesh模型上sample更多点及三维物体姿态估计
  7. vue A对象赋值给B对象,修改B属性会影响到A问题
  8. nohup启动后台进程并重定向
  9. Centos6.5镜像下载
  10. PAT(B)1003 我要通过!(Java)