boost::shared_ptr 智能指针 可以共享所有权的只能指针,看如下小例子
#include <iostream>
#include "boost/shared_ptr.hpp"
#include <string>
using namespace std;
//定义一个结构体,表示是否有人在家
struct SomeOneAtHome{
SomeOneAtHome(){
cout<<"one come in"<<endl;
}
~SomeOneAtHome(){
cout<<"go out of the home"<<endl;
}
void do_something(){
cout<<"do smoething in home"<<endl;
}
};
/** test1 输出如下,一个人走进来了,又出去了
one come in
the sample now has 1 references
go out of the home
**/
void test1(){
boost::shared_ptr<SomeOneAtHome> sp1(new SomeOneAtHome());
cout<<" the sample now has " << sp1.use_count()<<" references"<<endl;
}
/**
* test2输出如下,一个人走进来了,没提示出去
* one come in
* **/
void test2(){
SomeOneAtHome *p2 = new SomeOneAtHome();
}
/**
* test3输出如下
* 先报错
* 很多 go out of the home 这是把这个对象杀死了,然后分解带出去了?
*/
void test3(){
SomeOneAtHome *p2 = new SomeOneAtHome();
delete[]p2;//把这个人杀死,
}
/**
* test4 输出如下
one come in
now there has 1 persons
now there has 2 persons
now there has 2 persons
now there has 1 persons
go out of the home
now there has 0 persons
* */
void test4(){
boost::shared_ptr<SomeOneAtHome> person1(new SomeOneAtHome());//一个人A进来了
cout<<"now there has " << person1.use_count()<<" persons"<<endl;//输出1
boost::shared_ptr<SomeOneAtHome> person2 = person1; //A背了一个B
cout<<"now there has " << person1.use_count()<<" persons"<<endl;//输出2
cout<<"now there has " << person2.use_count()<<" persons"<<endl;//输出2
person1.reset();
cout<<"now there has " << person2.use_count()<<" persons"<<endl;//输出1
person2.reset();
cout<<"now there has " << person2.use_count()<<" persons"<<endl;//输出0
}
int main() {
// test1();
// test2();
// test3();
test4();
return 0;
}
boost::shared_ptr的管理机制其实并不复杂,就是对所管理的对象进行了引用计数,当新增一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数加一;减少一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数减一,如果该对象的引用计数为0的时候,说明没有任何指针对其管理,才调用delete释放其所占的内存。
上面的那个例子可以的图示如下(test4):
-
person1对SomeOneAtHome对象进行管理,其引用计数为1
-
增加person2对SomeOneAtHome对象进行管,其引用计数增加为2
-
person1释放对SomeOneAtHome对象进行管理,其引用计数变为1
-
person2释放对SomeOneAtHome对象进行管理,其引用计数变为0,该对象被自动删除
boost::shared_ptr的特点:
和前面介绍的boost::scoped_ptr相比,boost::shared_ptr可以共享对象的所有权,因此其使用范围基本上没有什么限制(还是有一些需要遵循的使用规则,下文中介绍),自然也可以使用在stl的容器中。另外它还是线程安全的,这点在多线程程序中也非常重要。
boost::shared_ptr的使用规则:
boost::shared_ptr并不是绝对安全,下面几条规则能使我们更加安全的使用boost::shared_ptr:
-
避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放
-
shared_ptr并不能对循环引用的对象内存自动管理(这点是其它各种引用计数管理内存方式的通病)。
-
不要构造一个临时的shared_ptr作为函数的参数。
如下列代码则可能导致内存泄漏:
void test()
{
foo(boost::shared_ptr<SomeOneAtHome>(new SomeOneAtHome()),g());
}
正确的用法为:
void test()
{
boost::shared_ptr<SomeOneAtHome> sp (new SomeOneAtHome());
foo(sp,g());
}
参考博客: