boost学习笔记之Pointer Container库

来源:互联网 发布:网络信号发生器 编辑:程序博客网 时间:2024/05/16 14:03

当我们需要在stl的库中装入多态类的对象时,通常的做法是在容器里装入父类的指针,然后手动释放,如我有以下两个类

class Light{  ....}class PointLight:public Light{   ...}std::vector<Light*> lights;lights.push_back(new PointLight());

上面的做法有如下几点弊端:

1.容易忘记释放掉指针,造成内存泄漏;

2不是异常安全的


boost中的Pointer Container库为我们提供了一种安全的方法来实现容器中的多态,并且其官方文档中也列举了一些优点如异常安全、速度快(相对于smart pointer而言)等,有兴趣的读者可以自己去看,这里讲下它的使用方法。

基本使用

boost::ptr_vector<Light> lights;lights.push_back(new PointLight());
如上所示,当lights这个对象柝构里会自动释放掉其包含的指针指向的对象。

间接接口

lights[0].getColor();
从上可以看出,我们取出的元素可以像对象而不是指针一样使用

关联容器

对于stl中的几乎所有窗口pointer container库几乎都提供了相应的类,当然也包括关联窗口。

当我们想使用boost::ptr_set这个类时,必须要求这个类的<操作符有定义,如
inline bool operator<(const Light& l1,const Light& l2){    return l1.getColor().getRed() < l2.getColor().getRed();}
boost::ptr_set<Light> lights;
lights.insert(new PointLight());
lights.insert(new PointLight());

对于boost::multimap这个类要注意,当向里插入的时候键值必须是一个左值(由于要确保异常安全),否则编译会不通过,如
boost::ptr_multimap<std::string,Light> lights;string a = "a",b="b";lights.insert(a,new PointLight());lights.insert(b,new PointLight());
如下代码会报错
lights.insert("aa",new PointLight());

空指针

默认情况下,如果你插入一个空指针会抛出异常的,如果你想允许插入空指针,则必须提前声明,如
boost::ptr_vector<boost::nullable<Light>> lights;lights.push_back(NULL);
一旦你允许空指针,则使用前必须检查,如
typedef boost::ptr_vector<boost::nullable<Light>> Light_type;for(Light_type::iterator i = lights.begin();     i != lights.end(); ++i ){    if( !boost::is_null(i) ) // always check for validity        i->getColor();}
或者如何容器支持随机存取的话也可以用如下的方法
for( Light_type::size_type i = 0u;      i != lights.size(); ++i ){    if( !lights.is_null(i) )         lights[i].getColor();}

注意对于ptr_set和ptr_multiset来说这显然空指针显然没意义。












原创粉丝点击