C ++实现纯虚拟类的实例的集合

时间:2009-09-26 05:54:17

标签: c++ polymorphism pure-virtual

我在跨平台C ++中工作,并且有一些类定义如下:(本例中大大简化了)

class ExampleBase
{
public:
    ExampleBase( int blah ) : blah_test(blah) { }

    virtual void DoSomething( ) = 0;
private:
    int blah_test;
};

class ExampleImplementer : public ExampleBase
{
public:
    ExampleImplementer( ) : ExampleBase( 5 ) { }

    virtual void DoSomething( ) { /* unique implementation here */ }
};

最初我只有一个类,我在std :: vector中存储了一堆实例,并通过const引用传递。但是现在我需要一个基类(我想保持纯虚拟)和一些多态实现类。

拥有任何实现实例的集合的最佳方法是什么,并且仍然具有无泄漏的简单内存管理,例如将堆栈分配为std :: vector?

  • 显然我不能有std :: vector< ExampleBase>现在,因为std :: vector要求类是非纯虚拟的(因为它进行内部分配/复制等)。我不希望我的代码的用户意外地创建ExampleBase的实例,因为这是错误的。我还希望避免任何物体切片或任何其他恶意的可能性。

  • std::auto_ptr的数组可以完成这项工作,但是我必须处理所有的初始化,寻找一个“免费插槽”,没有迭代器等。所有这些似乎有点疯狂这个轮子重新发明了。

  • boost::ptr_vector看起来很有前途,但它的行为有点奇怪,因为在Linux上构建它需要ExampleBase是非纯虚拟的 - 我不明白为什么......所以{{1出来了。

这似乎是一个简单的,可能是非常常见的情况。那么最好的方法是什么?我对任何其他标准或提升方式持开放态度:以“最佳”为准。

4 个答案:

答案 0 :(得分:6)

如果你可以拥有Boost,

boost::ptr_vector就是你的选择。它应该适用于您的场景 - 如果没有,那么其他错误,所以请发布错误消息。

或者,您可以选择std::vector< boost::shared_ptr<ExampleBase> >。这不太理想,因为引用计数会增加一些开销,特别是在调整vector的大小时,但是否则是一个有效的解决方案。

如果您的实现支持TR1(最新版本的g ++和MSVC),那么您可以使用std::tr1::shared_ptr代替。这实际上可能更优越,因为STL实现可以根据一些内部知识自由优化 - 例如,在MSVC中,std::vector知道它可以使用swap而不是std::tr1::shared_ptr的复制构造函数,并做到这一点,避免不断的refcount更改。

答案 1 :(得分:3)

有几种选择。

  • 使用boost :: ptr_vector作为容器。它甚至应该与抽象的基础classe一起工作。只需确保您的基类包含虚拟析构函数
  • 使用多个容器直接管理派生类的不同对象,并创建另一个仅使用指针的容器。这可能很麻烦,也会迫使您考虑何时/如果指针无效。但它也具有将相同类型的对象保持在一起的优点。
  • 使用智能指针(如boost的共享所有权指针)并将其存储到容器中。如果你不想共享所有权,C ++ 0x将提供另一个漂亮的智能指针,其开销较小:unique_ptr。不幸的是,在C ++ 03中没有很好的模拟。
  • 使用其他形式的“handle”,一个通过带有值语义的指针包装和管理多态对象的对象(这将是另一个可以命名为“clone_ptr”的智能指针)。

答案 2 :(得分:1)

boost::shared_ptr

答案 3 :(得分:1)

如果你可以使用boost,请尝试指针容器

http://www.boost.org/doc/libs/1_40_0/libs/ptr_container/doc/ptr_container.html