boost智能指针:
scoped_ptr <boost/scoped_ptr.hpp>简单的单一对象的唯一所有权。不可拷贝。//一旦离开作用域所指对象立即释放
scoped_array <boost/scoped_array.hpp>简单的数组的唯一所有权。不可拷贝。//管理数组
shared_ptr <boost/shared_ptr.hpp>在多个指针间共享的对象所有权。//指向一个对象该对象的引用计数加1,当引用计数将为0时所指对象立即被销毁,用于管理对象生命周期。可复制。
shared_array <boost/shared_array.hpp>在多个指针间共享的数组所有权。//管理数组
weak_ptr <boost/weak_ptr.hpp>一个属于 shared_ptr 的对象的无所有权的观察者。//弱引用,不增加对象的引用计数,但可以提升为shared_ptr因此可以通过提升判断对象是否还存活,若提升失败则所指对象不存在。提升操作是线程安全的。可复制。
intrusive_ptr <boost/intrusive_ptr.hpp>带有一个侵入式引用计数的对象的共享所有权。
这些只能指针指向被管理的对象A,且这些指针本身就是对象(带有计数并指向对象A的指针对象),这些指针都是值语义即其拷贝操作对原来无关,要么是栈对象、其它对象数据成员、容器元素。
使用方法:
shared_ptr<T> one(new T);//声明并初始化一个指向T类型对象的智能指针,,值语义:share_ptr<T> two=one。
几个比较重要的成员函数:
*one成为所指对象的引用即可用于T类型对象的任何操作;
one->fun()//假设T对象有fun这个成员函数,则这里是one所指对象的成员函数fun的调用;
one.get()//返回的管理对象的指针即一个T对象指针;
one.use_count()//获取被管理对象的计数;
one.swap(所指对象同为T的智能指针two)//交换one和two所指的内容;
one.unique()//被管理对象是否计数为1;
one.reset(T* p)//将one所指对象重置为同类型T的对象p
weak_ptr:weak_ptr必须从一个share_ptr或另一个weak_ptr转换而来,进行该对象的内存管理的是那个强引用的share_ptr,weak_ptr只是提供了对管理对象的一个访问手段。
weak_ptr提升为shared_ptr:weak_ptr<T> third(one); shared_ptr<T> two(third.lock());//two等于weak_ptr提升返回的shared_ptr对象
third.expired()//返回指向的对象是否过期
third.use_count()//返回指向的对象的计数即有多少个shared_ptr指向这个对象,注意weak_ptr不增加对象的计数
scoped_ptr:不能转换所有权
boost::scoped_ptr所管理的对象生命周期仅仅局限于一个区间(该指针所在的"{}"之间),无法传到区间之外,这就意味着boost::scoped_ptr对象是不能作为函数的返回值的(std::auto_ptr可以)。
不能共享所有权这点和std::auto_ptr类似。这个特点一方面使得该指针简单易用。另一方面也造成了功能的薄弱——不能用于stl的容器中。
不能用于管理数组对象
由于boost::scoped_ptr是通过delete来删除所管理对象的,而数组对象必须通过deletep[]来删除,因此boost::scoped_ptr是不能管理数组对象的,如果要管理数组对象需要使用boost::scoped_array类。
初始化:scoped_ptr<T> four(new T);
four.reset(T* p)//删除所存储的指针所指向的对象,然后存储一个 p 的拷贝,p 必须是经由一个 C++ 的 new 表达式动态分配的或者是 0
*four//返回所指对象的引用
T* p=four.get() //返回所存储的T类型指针
four->fun()//调用所指T类型对象的成员fun函数
get()释放所管理的对象,管理另外一个对象
four.swap(scoped_ptr<T>& b)//交换four和b锁管理的对象
避免使用匿名 shared_ptr 临时变量去存储内容,如
void bad() {shared_ptr<T>* one=new shared_ptr<T>(new T)//这是要闹哪样?编译都过不了,不要再将shared_ptr堆上分配了。f(shared_ptr<int>(new int(2)), g());//函数参数的求值顺序是不确定的,new int(2) 首先被求值,g() 第二个是有可能的,如果 g 抛出一个异常,我们永远也不可能到达 shared_ptr 的构造函数。
}
智能指针一个用处是管理对象的生命周期。这里看订阅者模式:订阅者要查看发布者是否还在,发布者要查看订阅者是否还存在
#include<iostream> #include<unistd.h> #include<vector> #include<boost/shared_ptr.hpp> #include<boost/weak_ptr.hpp> using namespace std; using namespace boost; class Observer;//订阅者,脑残粉 class Observable{//发布者,博主 public: void register_(shared_ptr<Observer> a);//添加订阅者 void notify();//通知脑残粉们本博主有新动态喔~~~ private: vector<weak_ptr<Observer> > vec;//存放脑残粉的容器 }; class Observer{//脑残粉 public: Observer(weak_ptr<Observable> a):blog(a){ } void get(shared_ptr<Observer> a){//a是指向Observer对象的智能指针 shared_ptr<Observable> obj(blog.lock());//提升blog,若成功则表明博主还在,提升失败博主不在了 if(obj){ //shared_ptr<Observer> a(this);//这样写会出错,在博主notif后调用it->update()发现管理对象不在了,这点我也很纳闷... obj->register_(a); } else{ cout<<"脑残粉:博主都不在了,呜呜呜~~~~"<<endl; } } void update(){ cout<<"脑残粉:收到博主的新动态,好happy~~~"<<endl; } private: weak_ptr<Observable> blog;// }; void Observable::register_(shared_ptr<Observer> a){//添加一个脑残粉 weak_ptr<Observer> x(a);//weak_ptr必须由shared_ptr和weak_ptr构造 vec.push_back(x); } void Observable::notify(){//告诉脑残粉们新动态 vector<weak_ptr<Observer> >::iterator it=vec.begin(); while(it!=vec.end()){ shared_ptr<Observer> obj(it->lock());//提升weak_ptr,成功表明粉丝还在,失败表明粉丝不在了 if(obj.use_count()>=1){ obj->update(); it++; } else{ it=vec.erase(it); } } } int main(){ shared_ptr<Observable> csdn(new Observable); weak_ptr<Observable> temp(csdn); shared_ptr<Observer> obj(new Observer(temp)); obj->get(obj);//这里get(obj)实属无奈,因为23和45行处有问题...会出现:boost::shared_ptr<T>::operator->() const [with T = Observer]: Assertion `px != 0' failed.运行错误 csdn->notify();//输出:脑残粉:收到博主的新动态,好happy~~~ obj.reset();//删除订阅者后博主无粉丝 csdn->notify();//无输出,因为唯一的粉丝都被删除了: shared_ptr<Observer> obj2(new Observer(temp)); csdn.reset();//删除博主后粉丝无法订阅 obj2->get(obj2);//输出:脑残粉:博主都不在了,呜呜呜~~~~ return 0; }
脑残粉:收到博主的新动态,好happy~~~
脑残粉:博主都不在了,呜呜呜~~~~