設定
class Base
{
public:
Base();
virtual ~Base();
int getType();
protected:
int type;
};
class DerivedA : public Base
{
public:
DerivedA() { this->type = 1; };
~DerivedA();
int getA() { return 1;};
};
class DerivedB : public Base
{
public:
DerivedB() { this->type = 2; };
~DerivedB();
int getB() { return 2;};
};
目標
両方の派生クラスのオブジェクトを含むベクトルを持ち、子固有のメソッドにアクセスできるようにします。
現在の「解決策」
int main()
{
typedef boost::ptr_vector<Base> BasePtr;
BasePtr vec;
// Fill vec with some stuff
vec.push_back(new DerivedA());
vec.push_back(new DerivedB());
vec.push_back(new DerivedA());
vec.push_back(new DerivedB());
typedef BasePtr::iterator BaseIter;
for ( BaseIter it = vec.begin(); it != vec.end(); it++ ) {
if (it->getType() == 1) {
std::cout << it->getA() << '\n';
} else {
std::cout << it->getB() << '\n';
}
}
return 0;
}
問題
明らかに、「it」はDerivedAまたはDerivedBとして認識されないため、子固有のメソッドにアクセスできません。何らかの形のキャストが必要なので、質問は次のとおりだと思います。
イテレータを正しい派生クラスに適切にキャストするにはどうすればよいですか?
たぶん、このシナリオ全体を構築するためのより良い方法がありますか?
編集: 私は少し不明確だったようです。派生クラスのメソッドの目的は根本的に異なります。派生クラスArmorとWeaponを持つ基本クラスItemについて考えてみます。
この例では、たとえば、Weaponにfloatを返す可能性のある関数getDamage()がある理由がわかります。
この機能はアーマーには必要なく、似たようなものもありません。
この例では、ベクターを、任意の数とタイプのアイテムを含むことができる在庫として見ることができます。たぶん、スタックといくつかの用途があるアイテムでさえ(ポーションかもしれません)