简体   繁体   English

C ++存储模板结构

[英]C++ storing template structures

I have a base structure FooBase : 我有一个基本结构FooBase

struct FooBase { };

Then I create a template structure Foo which is a child of FooBase : 然后创建一个模板结构Foo ,它是FooBase的子FooBase

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

In some class I create a vector of FooBase and add instances of Foo in it: 在某些类中,我创建一个FooBase的向量,并在其中添加Foo实例:

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

Then I needed to access the stored data, but I'm getting predictable and obvious error about an absence of the member foo in FooBase 然后,我需要访问存储的数据,但是关于FooBase缺少成员foo ,我得到了可预见的明显错误

FooVector[0].foo

I can not write something like 我不能写这样的东西

Foo <Bar> fooInstance = FooVector[0]

since I don't know the template parameter. 因为我不知道template参数。

How do I store instances of Foo in the vector so I can access them later. 如何在向量中存储Foo实例,以便以后可以访问它们。 Note, that I don't know the template parameter at the last step - when reading data from the vector. 请注意,从向量中读取数据时,我不知道最后一步的template参数。

PS NO BOOST ALLOWED! PS没有助推!

What happens here, is that in your 在这里发生的是

FooVector.push_back ( fooInstance );

line, C++ silently invokes the copy constructor of FooBase , because you can only keep objects of that type in your vector. 一行,C ++静默调用FooBase的副本构造FooBase ,因为您只能将这种类型的对象保留在向量中。 Since Foo inherits publicly from FooBase the method FooBase::FooBase(FooBase const&) can be called with an object of type Foo . 由于FooFooBase公开继承, FooBase 可以使用Foo类型的对象调用FooBase::FooBase(FooBase const&) 方法

So, you're not really storing Foo s, but in fact FooBase s. 因此,您并不是真正存储Foo ,而是实际上存储FooBase To do what you want to do you need an std::vector<FooBase*> or std::vector<std::shared_ptr<FooBase> > . 要执行您想做的事情,您需要一个std::vector<FooBase*>std::vector<std::shared_ptr<FooBase> >

However, the contents of your vector, will still lack a foo member, because the static type is still not Foo . 但是,向量的内容仍将缺少foo成员,因为静态类型仍不是Foo To get around this, you have some options. 为了解决这个问题,您有一些选择。 You could dynamic_cast or static_cast your FooBase* into a Foo* and then access its foo member. 可以 dynamic_caststatic_castFooBase*Foo* ,然后访问其foo成员。 But that could break, since the FooBase* pointers might actually hold another type than Foo . 但这可能会中断,因为FooBase*指针实际上可能拥有Foo之外的另一种类型。

Why don't you just use an std::vector<Foo<Bar> > instead? 为什么不只使用std::vector<Foo<Bar> >代替呢?

You are slicing here: 您在这里切片:

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

You are pushing a Foo<Bar> into a vector of FooBase so you only get a FooBase object stored. 您正在将Foo<Bar>推入FooBase的向量中,因此只能存储FooBase对象。 This 这个

FooVector[0]

returns a reference to a FooBase which knows nothing about Foo<Bar> . 返回对FooBase的引用,该引用对Foo<Bar>一无所知。 You could store Foo<Bar> directly: 您可以直接存储Foo<Bar>

vector<Foo<Bar>> FooVector;

or store pointers or smart pointers to FooBase , but then you will have to dynamic_cast the elements to Foo<Bar>* anyway, which isn't a very nice solution. 或存储指向FooBase指针或智能指针,但是FooBase ,您都必须将元素dynamic_cast到Foo<Bar>* ,这不是一个很好的解决方案。

As mentioned in previous answers, you are slicing Bar into FooBase objects. 如前面的答案中所述,您正在将Bar切片为FooBase对象。 Your vector has to store references to Foo objects rather than the object itself. 向量必须存储对Foo对象的引用,而不是对象本身。

The easiest way to accomplish this is to use one of the smart_ptr types from the boost library. 完成此操作的最简单方法是使用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() );

If you store the pointer itself into the vector you'll have problems with memory management, using the boost shared_ptr type will handle allocation for you automatically. 如果将指针本身存储到向量中,则将在内存管理方面遇到问题,使用boost shared_ptr类型将自动为您处理分配。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM