1

我在跨平台 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 是非纯虚拟的 - 我不明白为什么......所以boost::ptr_vector出来了。

这似乎很简单,而且可能很常见。那么最好的方法是什么?我对任何其他标准或增强方式持开放态度:以“最好”为准。

4

4 回答 4

6

boost::ptr_vector如果您可以拥有 Boost,那么这是要走的路。它应该适用于您的场景 - 如果不适用,那么还有其他问题,所以请发布错误消息。

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

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

于 2009-09-26T06:01:21.960 回答
3

有几个选项。

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

boost::shared_ptr

于 2009-09-26T05:59:46.893 回答
1

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

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

于 2009-09-26T06:00:21.727 回答