当我们需要在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();从上可以看出,我们取出的元素可以像对象而不是指针一样使用
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(); }