运行时类型信息

时间:2023-02-02 03:07:22

运行时类型信息

动态类型转换

一.向下造型

•动态类型转换(dynamic_cast)用于将基类类型的指针或引用转换为其子类类型的指针或引用,前提是子类必须从基类多态继承,即基类包含至少一个虚函数

class A 
{
virtual void foo (void) = 0;
};

class B : public A { ... };

–B b;
A* pa = &b;
B* pb = dynamic_cast<B*> (pa);
A& ra = b;
B& rb = dynamic_cast<B&> (ra);

二.类型检查

•动态类型转换会对所需转换的基类指针或引用做检查,如果其目标确实为期望得到的子类类型的对象,则转换成功,否则转换失败
–不是对指针或引用做类型转换,编译错误
–转换目标和源不具多态继承性,编译错误
–转换源的目标对象非目标类型,运行错误

三.转换失败

•针对指针的动态类型转换,以返回空指针(NULL)表示失败,针对引用的动态类型转换,以抛出bad_cast异常表示失败

    –A* pa = ...; 
B* pb = dynamic_cast<B*> (pa);
if (pb == NULL)
cout << "转换失败!" << endl;
–A& ra = ...;
try
{
B& rb = dynamic_cast<B&> (ra);
}
catch (bad_cast& ex)
{
cout << "转换失败!" << endl;
}

typeid操作符

一.typeinfo对象

•typeid操作符既可用于类型也可用于对象
–int x;
typeid (int);
typeid (x);

•typeid操作符返回typeinfo对象的常引用

#include <typeinfo>
–typeinfo类的成员函数name(),返回空字符结尾的类型名
cout << typeid ( char (*(*[5]) (short (*) (int, long))) (float, double) ).name () << endl;
// A5_PFPFcfdEPFsilEE
–typeinfo类支持“==”和“!=”操作符,可直接用于类型相同与否的判断
if (typeid (*human) == typeid (Student))
{ ... }

二.动态与静态类型信息

•当typeid作用于基类类型的指针或引用的目标时,若基类包含至少一个虚函数,即存在多态继承,
该操作符所返回的类型信息将由该指针或引用的实际目标对象的类型决定,否则由该指针或引用本身的类型决定

class A {}; 
class B : public A
{
virtual void foo (void) {}
}; // 继承
class C : public B {}; // 多态继承
–C c;
A& a = c;
cout << typeid (a).name () << endl; // 1A - 静态类型
B& b = c;
cout << typeid (b).name () << endl; // 1C - 动态类型