给定一个 E 类型的对象和一个指向 D 子对象的指针,从 D 子对象定位到最左侧的 A 子对象,可进行三个转换。可以从 D 指针到 E 指针执行 dynamic_cast 转换,然后从 E 到 B 执行转换(dynamic_cast 或隐式转换),最后从 B 到 A 执行隐式转换。例如:
// dynamic_cast_5.cpp
// compile with: /c /GR
class A {virtual void f();};
class B : public A {virtual void f();};
class C : public A { };
class D {virtual void f();};
class E : public B, public C, public D {virtual void f();};
void f(D* pd) {
E* pe = dynamic_cast<E*>(pd);
B* pb = pe; // upcast, implicit conversion
A* pa = pb; // upcast, implicit conversion
}
dynamic_cast 运算符还可以使用执行 “相互转换”。使用同一个类层次结构可能进行指针转换,例如: 从B 子对象转换到D子对象(只要整个对象是类转换型E。
考虑相互转换,实际上从指针转换到 D 到指针到最左侧的 A 子对象只要两个步骤。可以从 D 到 B 执行相互转换,然后从 B 到 A 执行隐式转换。例如:
// dynamic_cast_6.cpp
// compile with: /c /GR
class A {virtual void f();};
class B : public A {virtual void f();};
class C : public A { };
class D {virtual void f();};
class E : public B, public C, public D {virtual void f();};
void f(D* pd) {
B* pb = dynamic_cast<B*>(pd); // cross cast
A* pa = pb; // upcast, implicit conversion
}
通过 dynamic_cast 将 null 指针值转换到目标类型的 null 指针值。
当您使用 dynamic_cast < type-id > ( expression )时,如果expression无法安全地转换成类型 type-id,则运行时检查会引起变换失败。例如:
// dynamic_cast_7.cpp
// compile with: /c /GR
class A {virtual void f();};
class B {virtual void f();};
void f() {
A* pa = new A;
B* pb = dynamic_cast<B*>(pa); // fails at runtime, not safe;
// B not derived from A
}
指针类型的非限定转换的值是 null 指针。引用类型的非限定转换会引发 bad_cast 异常。 如果 expression 不指向也不引用有效的对象,则__non_rtti_object 异常引发。
有关异常 __non_rtti_object 的解释,请参见 typeid。
以下示例创建基类(结构 A)指针,为一个对象(结构 C)。这以及在该情况是虚函数,启用运行时多态性。
该示例也在层次结构中调用非虚函数。
// dynamic_cast_8.cpp
// compile with: /GR /EHsc
#include <stdio.h>
#include <iostream>
struct A {
virtual void test() {
printf_s("in An");
}
};
struct B : A {
virtual void test() {
printf_s("in Bn");
}
void test2() {
printf_s("test2 in Bn");
}
};
struct C : B {
virtual void test() {
printf_s("in Cn");
}
void test2() {
printf_s("test2 in Cn");
}
};
void Globaltest(A& a) {
try {
C &c = dynamic_cast<C&>(a);
printf_s("in GlobalTestn");
}
catch(std::bad_cast) {
printf_s("Can't cast to Cn");
}
}
int main() {
A *pa = new C;
A *pa2 = new B;
pa->test();
B * pb = dynamic_cast<B *>(pa);
if (pb)
pb->test2();
C * pc = dynamic_cast<C *>(pa2);
if (pc)
pc->test2();
C ConStack;
Globaltest(ConStack);
// will fail because B knows nothing about C
B BonStack;
Globaltest(BonStack);
}










