C++ RTTI

一、dynamic_cast

dynamic_cast (expression)
这个表达式将 expression 转换为一个 type-id 类型的对象。 Type-id 必须是一个指针、指向一个已经定义类的类型或一个指向 VOID 的指针。 Expression 的类型必须是一个指针,如果 type-id 是一个指针;当 type-id 是一个引用的时候必须是一个左值。

1、

class B { ... };
class C : public B { ... };
class D : public C { ... };
void f(D* pd)
{
   C* pc = dynamic_cast<C*>(pd);   // ok: C 是一个直接的基类
                                 // pc 指向 pd 的 C 子对象
   B* pb = dynamic_cast<B*>(pd);   // ok: B 是一个间接的基类
                                 // pb 指向 pd 的 B 子对象
   ...
}

这个类型转换叫做向上转型,因为它将一个指针在其继承层次向上转型,即从一个继承类到其基类。向上转型是隐式转换。

2、

如果 type-id 是一个 void* ,运行时检查将决定表达式的实际类型。结果是一个到 expression 指向的完整对象。例如:

class A { ... };
class B { ... };
void f()
{
   A* pa = new A;
   B* pb = new B;
   void* pv = dynamic_cast<void*>(pa);
   // pv 指向一个 A 类型的对象
   ...
   pv = dynamic_cast<void*>(pb);
   // pv 指向一个 B 类型的对象
}

3、

如果 type-id 不是 void* ,运行时检查指向 expression 的对象能否转换为指向 type-id 类型的对象。
如果 expression 类型是 type-id 的基类,运行时检查是否 expression 实际是一个指向 type-id 类型的完整对象,如果是,结果返回指向 type-id 类型的完整对象,否则返回 NULL 。例如:

class B { ... };
class D : public B { ... };
void f()
{
   B* pb = new D;                     // unclear but ok
   B* pb2 = new B;
   D* pd = dynamic_cast<D*>(pb);      // ok: pb 实际指向 D
   ...
   D* pd2 = dynamic_cast<D*>(pb2);   // pb2 实际指向 B 而不是 D
                                    // 转换失败, pd2 是 NULL
   ...
}

向下类型转换之所以这么说是因为其从类继承层次的父类向子类转换。
在多重继承的情况,可能导致二义性。看一下下面的类继承层次:

posted @ 2025-10-24 17:21  wuya178  阅读(5)  评论(0)    收藏  举报