kind
仮想関数の代わりにフィールドを使用して動的ディスパッチを行う従来のコードがあります。次のようになります。
// Base struct shared by all subtypes
// Plain-old data; can't use virtual functions
struct POD
{
int kind;
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
};
enum Kind { Kind_Derived1, Kind_Derived2, Kind_Derived3 /* , ... */ };
struct Derived1: POD
{
Derived1(): kind(Kind_Derived1) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
struct Derived2: POD
{
Derived2(): kind(Kind_Derived2) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
struct Derived3: POD
{
Derived3(): kind(Kind_Derived3) {}
int GetFoo();
int GetBar();
int GetBaz();
int GetXyzzy();
// ... plus other type-specific data and function members ...
};
// ... and so on for other derived classes ...
POD
クラスの関数メンバーは次のように実装されます。
int POD::GetFoo()
{
// Call kind-specific function
switch (kind)
{
case Kind_Derived1:
{
Derived1 *pDerived1 = static_cast<Derived1*>(this);
return pDerived1->GetFoo();
}
case Kind_Derived2:
{
Derived2 *pDerived2 = static_cast<Derived2*>(this);
return pDerived2->GetFoo();
}
case Kind_Derived3:
{
Derived3 *pDerived3 = static_cast<Derived3*>(this);
return pDerived3->GetFoo();
}
// ... and so on for other derived classes ...
default:
throw UnknownKindException(kind, "GetFoo");
}
}
POD::GetBar()
、POD::GetBaz()
、POD::GetXyzzy()
、および他のメンバーも同様に実装されます。
この例は単純化されています。実際のコードには、 の約 12 の異なるサブタイプPOD
と、数十のメソッドがあります。の新しいサブタイプPOD
と新しいメソッドがかなり頻繁に追加されるため、そのたびにこれらすべてのswitch
ステートメントを更新する必要があります。
virtual
これを処理する一般的な方法は、クラスで関数メンバーを宣言することPOD
ですが、オブジェクトが共有メモリに存在するため、これを行うことはできません。これらの構造体が単純な古いデータであることに依存するコードがたくさんあるため、共有メモリ オブジェクトで仮想関数を使用する方法を見つけられたとしても、それはしたくありません。
switch
そのため、サブタイプ メソッドの呼び出し方法に関するすべての知識が、数ダースの関数内の数ダースのステートメントに分散するのではなく、1 か所に集中するように、これをクリーンアップする最善の方法に関する提案を探しています。
私が思いつくのはPOD
、冗長性を最小限に抑えるためにテンプレートをラップして使用するある種のアダプター クラスを作成できるということです。しかし、その道を歩み始める前に、他の人がこれにどのように対処したかを知りたい.