C ++存储模板结构

时间:2012-08-28 08:14:49

标签: c++ class templates struct storage

我有一个基础结构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的实例,以便稍后访问它们。 请注意,我从最后一步知道模板参数 - 从向量中读取数据时。

P.S。没有提升!

3 个答案:

答案 0 :(得分:2)

这里发生的是你的

FooVector.push_back ( fooInstance );

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

所以,你并没有真正存储Foo,而实际上是FooBase。要执行您想要的操作,您需要std::vector<FooBase*>std::vector<std::shared_ptr<FooBase> >

但是,矢量的内容仍然缺少foo成员,因为静态类型仍然不是Foo。为了解决这个问题,你有一些选择。您可以 dynamic_caststatic_castFooBase*加入Foo*,然后访问其foo成员。但这可能会破坏,因为FooBase*指针可能实际上保持另一种类型而不是Foo

为什么不使用std::vector<Foo<Bar> >呢?

答案 1 :(得分:1)

你在这里切片:

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

您正在将Foo<Bar>推送到FooBase的向量中,因此您只能存储FooBase个对象。此

FooVector[0]

返回对FooBase的引用,Foo<Bar>Foo<Bar>一无所知。您可以直接存储vector<Foo<Bar>> FooVector;

FooBase

或存储指向Foo<Bar>*的指针或智能指针,但是无论如何你必须将元素动态广播到{{1}},这不是一个非常好的解决方案。

答案 2 :(得分: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类型将自动为您处理分配。