我有一个基础结构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。没有提升!
答案 0 :(得分:2)
这里发生的是你的
FooVector.push_back ( fooInstance );
行,C ++以静默方式调用FooBase
的复制构造函数,因为您只能在向量中保留该类型的对象。由于Foo
从FooBase
公开继承,因此可以使用FooBase::FooBase(FooBase const&)
类型的对象调用方法Foo
。
所以,你并没有真正存储Foo
,而实际上是FooBase
。要执行您想要的操作,您需要std::vector<FooBase*>
或std::vector<std::shared_ptr<FooBase> >
。
但是,矢量的内容仍然缺少foo
成员,因为静态类型仍然不是Foo
。为了解决这个问题,你有一些选择。您可以 dynamic_cast
或static_cast
将FooBase*
加入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类型将自动为您处理分配。