はい、上記のようにポリモーフィズムを使用する必要があります。非常に複雑になりますが、関数が2つのオブジェクトを処理する必要がある場合。
派生が限定されたセットを形成し、お互いを知っている場合は、二重ディスパッチを使用できます。完璧ではありませんが、この特定のケースを解決します。
class DerivedA;
class DerivedB;
class DerivedC;
class BaseClass
{
public:
virtual ~BaseClass();
virtual void doSomethingWithBase( BaseClass & b2 ) = 0;
virtual void doSomethingWithDerivedA( DerivedA & da ) = 0;
virtual void doSomethingWithDerivedB( DerivedB & db ) = 0;
virtual void doSomethingWithDerivedC( DerivedC & dc ) = 0;
};
class DerivedA : public BaseClass
{
public:
void doSomethingWithBase( BaseClass & b2 )
{
b2.doSomethingWithDerivedA( *this );
}
void doSomethingWithDerivedA( DerivedA & da )
{
// implement for two DerivedA objects
}
void doSomethingWithDerivedB( DerivedB & db )
{
// implement for an A and B
}
void doSomethingWithDerivedC( DerivedC & dc )
{
// implement for an A and C
}
};
// implement DerivedB to call doSomethingWithDerivedB on its parameter
// implement DerivedC to call doSomethingWithDerivedC on its parameter.
あなたはアイデアを得る。呼び出し元から、どの 2 つのタイプがあるかを知る必要はなく、実際にこれを調べる必要もありません。しかし、実装をさらに追加する場合は、編集するコードが多くなり、ある種のルックアップ テーブルを検討する必要があります。
それ自体を定義するクラスが必要な場合は、ある種の仮想 ID を使用できます。
class BaseClass
{
public:
virtual int id() const = 0;
};
次に、クラスを取得して ID を明らかにし、これらの ID に基づいて、2 つのオブジェクトを処理するハンドラーをテーブルで見つけます。ID は int である必要はありません。名前の衝突を回避しやすくする文字列にすることができます。これは、派生クラスを知らない、またはお互いを知っている基本クラスの二重ディスパッチ メソッドよりも利点があります。拡張可能であること。また、すべてのペアを処理する必要はありません。