我在跨平台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出来了。
这似乎是一个简单的,可能是非常常见的情况。那么最好的方法是什么?我对任何其他标准或提升方式持开放态度:以“最佳”为准。
答案 0 :(得分:6)
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)
有几种选择。
答案 2 :(得分:1)
boost::shared_ptr
答案 3 :(得分:1)
如果你可以使用boost,请尝试指针容器
http://www.boost.org/doc/libs/1_40_0/libs/ptr_container/doc/ptr_container.html