欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

boost学习笔记之Pointer Container库 博客分类: boost C++boost编程

程序员文章站 2024-03-06 14:33:50
...

当我们需要在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 编程