smart_ptr之shared_ptr
智能指针的概念
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版本。
实例
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 *例子主要功能: 3 *1.测试引用计数的增减 4 *2.shared_from_this的使用 5 */ 6 #include<iostream> 7 #include<assert.h> 8 #include<vector> 9 #include<memory> 10 using namespace std; 11 void TestCount(shared_ptr<int>); 12 typedef vector<shared_ptr<int> > VS; 13 class self_shared:public enable_shared_from_this<self_shared> 14 { 15 public: 16 self_shared(int n):x(n){} 17 int x; 18 void print() 19 { 20 cout<<"self_shared: "<<x<<endl; 21 } 22 23 }; 24 int main() 25 { 26 shared_ptr<int> p(new int(100)); 27 cout<<"*p = "<<*p<<endl; 28 cout<<"use_count = "<<p.use_count()<<endl; 29 shared_ptr<int> q(p); 30 cout<<"use_count = "<<p.use_count()<<endl; 31 shared_ptr<int> pp = q; 32 cout<<"q.use_count() = "<<q.use_count()<<endl; 33 cout<<"pp.use_count() = "<<pp.use_count()<<endl; 34 p.reset(); 35 assert(pp); 36 cout<<"pp.use_cout() = "<<pp.use_count()<<endl; 37 if(!pp.unique()) 38 { 39 cout<<"I am not the unique\n"; 40 } 41 cout<<*pp<<endl; 42 cout<<"before TestCount, pp.use_count = "<<pp.use_count()<<endl; 43 TestCount(pp); 44 cout<<"after TestCount, pp.use_count = "<<pp.use_count()<<endl; 45 VS vs(10); 46 int i = 0; 47 for(auto pos = vs.begin(); pos != vs.end(); ++pos) 48 { 49 (*pos) = make_shared<int>(++i); 50 cout<<*(*pos)<<", "; 51 } 52 cout<<endl; 53 shared_ptr<int> ppp = vs[9]; 54 *ppp = 100; 55 cout<<" *vs[9] = "<<*vs[9]<<endl; 56 cout<<" vs[9].get() = "<<vs[9].get()<<endl; 57 cout<<" *vs[9].get() = "<<*(vs[9].get())<<endl; 58 auto sp = make_shared<self_shared>(313); 59 sp->print(); 60 cout<<"sp.use_count() = "<<sp.use_count()<<endl; 61 auto spp = sp->shared_from_this(); 62 spp->x = 1000; 63 spp->print(); 64 sp->print(); 65 cout<<"sp.use_count() = "<<sp.use_count()<<endl; 66 cout<<"spp.use_count() = "<<spp.use_count()<<endl; 67 return 0; 68 } 69 void TestCount(shared_ptr<int> p) 70 { 71 shared_ptr<int> q = p; 72 cout<<"in the TestCount, q.use_count = "<<q.use_count()<<endl; 73 }
编译后运行,输出结果如下: