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からパブリックに継承するため、 type のオブジェクトで呼び出すことができます。FooBaseFooBase::FooBase(FooBase const&) Foo

したがって、実際にはs を格納Fooしているのではなく、実際にはFooBases を格納しています。やりたいことをするには、std::vector<FooBase*>またはが必要std::vector<std::shared_ptr<FooBase> >です。

ただし、静的型はまだ ではないため、ベクトルの内容にはまだメンバーがありませ。これを回避するには、いくつかのオプションがあります。にアクセスしたり、そのメンバーにアクセスしたりできます。しかし、ポインターは実際には 以外の型を保持している可能性があるため、これは壊れる可能性があります。fooFoo dynamic_caststatic_castFooBase*Foo*fooFooBase*Foo

std::vector<Foo<Bar> >代わりにを使用してみませんか?

于 2012-08-28T08:23:34.147 に答える
1

ここでスライスしています:

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

Foo<Bar>のベクトルにa をプッシュしているFooBaseため、FooBaseオブジェクトのみが格納されます。これ

FooVector[0]

FooBaseは、 について何も知らないへの参照を返しますFoo<Bar>。直接保存できFoo<Bar>ます:

vector<Foo<Bar>> FooVector;

またはへのポインターまたはスマートポインターを保存しますFooBaseが、とにかく要素を動的にキャストする必要がありますがFoo<Bar>*、これはあまり良い解決策ではありません。

于 2012-08-28T08:22:14.320 に答える
0

前の回答で述べたように、 Bar を FooBase オブジェクトにスライスしています。ベクターは、オブジェクト自体ではなく Foo オブジェクトへの参照を保存する必要があります。

これを実現する最も簡単な方法は、boost ライブラリの smart_ptr タイプの 1 つを使用することです。

#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 に答える