boost学习笔记之Pointer Container库

当我们需要在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来说这显然空指针显然没意义。
   

你可能感兴趣的:(编程,C++,boost)