次のクラスがある場合:
class A
{
...
}
class B
{
...
}
class C : public A, public B
{
...
}
どこかでB
、私が持っているクラスのポインターが実際にクラスを指していることを検出しましC
たが、関数にはクラスへのポインターが必要です。A
クラスへのポインターを取得するにはどうすればよいA
ですか?
次のクラスがある場合:
class A
{
...
}
class B
{
...
}
class C : public A, public B
{
...
}
どこかでB
、私が持っているクラスのポインターが実際にクラスを指していることを検出しましC
たが、関数にはクラスへのポインターが必要です。A
クラスへのポインターを取得するにはどうすればよいA
ですか?
B*
オブジェクトを指すが確実にわかっている場合はC
、次のペアを使用できますstatic_cast
。
B* bp = new C();
C* cp = static_cast<C*>(bp);
A* ap = static_cast<A*>(cp);
継承階層全体にキャストする唯一の方法は、を使用することdynamic_cast
です。これには、型がポリモーフィックである必要があります(つまり、クラスには少なくとも1つの仮想メンバー関数が必要です。基本クラスのデストラクタはである必要があるためvirtual
、これは通常問題にはなりません。 )::
B* bp = new C();
A* ap = dynamic_cast<A*>(bp);
dynamic_cast
失敗した場合(つまり、bp
実際にを指していない場合C
)、NULLを返すという追加の利点があります。パフォーマンスコストがわずかになるという欠点があります(static_cast
実行時に実質的に無料です)。
コード
class A
{
};
class B
{
};
class C : public A, public B
{
};
int main() {
C c;
A *a = &c;
}
は C が既に A であるため有効であるため、代入は有効です。
あなたが示したように C が A から継承する場合、C* ポインターは A* ポインターに暗黙的に変換可能でなければなりません。コンパイラがこの継承関係を認識しないように、クラス C の宣言を含めていない可能性はありますか? それとも、あなたの質問で与えられたものとは異なる継承関係が実際にあるということですか? この問題を診断するには、いくつかのコードが役立ちます。
編集
質問の更新版に基づいて:
// Converts b to type A*, but only if it is actually
// of type C; otherwise, returns NULL
A* convertBtoAviaC(B* b) {
C* c = dynamic_cast<C*>(b);
return c; // note may be NULL, if b is not a C
}