0

我有一个基本结构FooBase

struct FooBase { };

然后我创建一个模板结构Foo,它是以下的子级FooBase

template <typename typeName> struct Foo : public FooBase { typeName* foo };

在某些类中,我创建了一个向量FooBase并在其中添加了实例Foo

vector <FooBase> FooVector
...    
Foo <Bar> fooInstance;
fooInstance.foo = new Bar();
FooVector.push_back ( fooInstance );

然后我需要访问存储的数据,但我得到了关于成员缺席的可预测且明显的foo错误FooBase

FooVector[0].foo

我不能写类似的东西

Foo <Bar> fooInstance = FooVector[0]

因为我不知道模板参数。

如何Foo在向量中存储实例,以便以后访问它们。请注意,我不知道最后一步的模板参数 - 从向量中读取数据时。

PS不允许提升!

4

3 回答 3

2

这里发生的事情是在你的

FooVector.push_back ( fooInstance );

行,C++ 静默调用 的复制构造函数FooBase,因为您只能在向量中保留该类型的对象。由于从方法中Foo公开继承,因此可以使用类型的对象调用。FooBaseFooBase::FooBase(FooBase const&) Foo

所以,你并不是真正存储Foos,而是实际上存储FooBases。要做你想做的事,你需要一个std::vector<FooBase*>or std::vector<std::shared_ptr<FooBase> >

但是,您的向量的内容仍然会缺少一个foo成员,因为静态类型仍然不是Foo. 为了解决这个问题,您有一些选择。你可以 dynamic_caststatic_cast你的FooBase*进入一个Foo*然后访问它的foo成员。但这可能会中断,因为FooBase*指针实际上可能包含另一种类型,而不是Foo.

你为什么不直接使用 anstd::vector<Foo<Bar> >呢?

于 2012-08-28T08:23:34.147 回答
1

你在这里切片:

vector <FooBase> FooVector
...    
Foo <Bar> fooInstance;
fooInstance.foo = new Bar();
FooVector.push_back ( fooInstance );

您正在将 a 推Foo<Bar>入向量中,FooBase因此您只会FooBase存储一个对象。这

FooVector[0]

返回对 aFooBase一无所知的引用Foo<Bar>。您可以Foo<Bar>直接存储:

vector<Foo<Bar>> FooVector;

或存储指向 的指针或智能指针FooBase,但是无论如何您都必须将元素动态转换为Foo<Bar>*,这不是一个很好的解决方案。

于 2012-08-28T08:22:14.320 回答
0

如前面的答案所述,您将 Bar 切片为 FooBase 对象。您的向量必须存储对 Foo 对象的引用,而不是对象本身。

最简单的方法是使用 boost 库中的 smart_ptr 类型之一。

#include <boost/shared_ptr.hpp>
#include <vector>
typedef std::vector< boost::shared_ptr<FooBase> > FooVector;
...
FooVector v;
v.push_back( new Bar() );

如果您将指针本身存储到向量中,您将遇到内存管理问题,使用 boost shared_ptr 类型将自动为您处理分配。

于 2012-08-28T09:07:43.913 回答