boost智能指针重塑订阅者模式

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()
{

f(shared_ptr<int>(new int(2)), g());//函数参数的求值顺序是不确定的,new int(2) 首先被求值,g() 第二个是有可能的,如果 g 抛出一个异常,我们永远也不可能到达 shared_ptr 的构造函数。

}
     shared_ptr<T>* one=new shared_ptr<T>(new T)//这是要闹哪样?编译都过不了,不要再将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~~~ 
脑残粉:博主都不在了,呜呜呜~~~~

你可能感兴趣的:(boost智能指针重塑订阅者模式)