さまざまなクラスの役割を知らなければ、言うのは難しいですが、A
とF
がインターフェースである場合(おそらくその場合)、A*
オブジェクトがインターフェースもサポートしているかどうかを尋ねる正しい方法F
はですdynamic_cast<F*>
。これにより、F
サポートされている場合はインターフェイスへのポインタが提供され、サポートされていない場合はnullポインタが提供されます。
F
それを超えて、インターフェースがインターフェースを拡張するA
かどうか、またはそれが完全に無関係であるかどうかを反映するかもしれません。それが拡張機能である場合、おそらく;F
から派生するはずです。A
拡張インターフェースを実装することがわかっているオブジェクトを作成するときは、そのアドレスをに割り当て、F*
将来のキャストをすべて回避します。(一般に、ポイントされたオブジェクトの一部が実装されないA*
ポイントに到達するまで、に割り当てないでください。)したがって、次のようになります。F
// interfaces...
class A {};
class F : public virtual A {};
// implementations of A...
class C : public virtual A {};
class B : public virtual A {};
// implementations of F (and also A, of course)
class E : public C, public virtual F {};
class D : public B, public virtual F {};
インターフェイスから派生する場合は、一般に、派生を仮想化することをお勧めします。(この場合、のすべての派生に必要ですA
。ただし、同じパターンが別のレベルで繰り返される可能性があるため、のインターフェイスを拡張する新しいクラスがあるため、インターフェイスF
からの派生は仮想であるというルールを採用する方が一般的に簡単です。)
F
が本当に関係ない場合はA
、1つのクラスが両方を実装して何をしているのかを尋ねることもできます。A
または、のいくつかの(多くの?)実装も実装することが理にかなっている場合は、次のインターフェイスの一部としてへのF
アクセスを提供することを検討してください。も実装するクラスは、この関数を。のようなものでオーバーライドします。F
A
F* A::getF() { return NULL; }
F
F* E::getF() { return this; }