此转换类型称为“向下转换”,因为它将在类层次结构下的指针,从给定的类移到该类派生的类。
对于多重继承,引入多义性的可能性。考虑下图中显示的类层次结构。
对于 CLR 类型,如果转换可以隐式执行,则 dynamic_cast 结果为 no-op,如果转换失败,则 MSIL isinst 指令将执行动态检查并返回 nullptr。
以下示例使用 dynamic_cast 以确定一个类是否为特殊类型的实例:
// dynamic_cast_clr.cpp
// compile with: /clr
using namespace System;
void PrintObjectType( Object^o ) {
if( dynamic_cast<String^>(o) )
Console::WriteLine("Object is a String");
else if( dynamic_cast<int^>(o) )
Console::WriteLine("Object is an int");
}
int main() {
Object^o1 = "hello";
Object^o2 = 10;
PrintObjectType(o1);
PrintObjectType(o2);
}
显示多重继承的类层次结构
显示多继承的类层次结构
指向类型 D 对象的指针可以安全地强制转换为 B 或 C。但是,如果 D 强制转换为指向 A 对象的指针,会导致 A 的哪个实例?这将导致不明确的强制转换错误。若要避免此问题,可以执行两个明确的转换。例如:
// dynamic_cast_4.cpp
// compile with: /c /GR
class A {virtual void f();};
class B {virtual void f();};
class D : public B {virtual void f();};
void f() {
D* pd = new D;
B* pb = dynamic_cast<B*>(pd); // first cast to B
A* pa2 = dynamic_cast<A*>(pb); // ok: unambiguous
}
当使用虚拟基类时,其他多义性问题会被引入。考虑下图中显示的类层次结构。
显示虚拟基类的类层次结构
在此层次结构中,A 是虚拟基类。对于虚拟基类的定义。给定一个 E 类实例和一个指向 A 子对象的指针,指向 B 指针的 dynamic_cast 将失败于多义性。必须先将强制转换回完整 E 对象,然后以明确的方式反向沿层次结构,到达正确的 B 对象。
考虑下图中显示的类层次结构。











