RTTI
RTTI(Run-Time Type Identification,运行时类型识别)
typeid
typeid是C++ 的关键字之一,返回值为type_info类对象的引用。
若表达式的类型为 含虚函数的类
,则typeid在运行时计算。否则在编译时进行计算。
typeid 既可以用在变量上又可以用在表达式上。如果表达式的类型在编译器就可以推断出来,那么表达式本身不会被执行 |
type_info是编译器相关的,但是其实现必须包含以下操作:
操作符 | 说明 |
---|---|
t1 == t2 | 如果两个对象t1和t2类型相同,则返回true;否则返回false |
t1 != t2 | 如果两个对象t1和t2类型不同,则返回true;否则返回false |
t.name() | 返回类型的C-style字符串,类型名字用系统相关的方法产生 |
t1.before(t2) | 返回指出t1是否出现在t2之前的bool值 |
type_info类提供了虚析构函数,以便用户能够将其作为基类。同时,它的默认构造函数、拷贝构造函数、赋值运算符被定义为private,导致用户无法生成相应的对象。
type_info对象只能由typeid这个友元函数进行生成。
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
class A{
public:
virtual void f(){}
};
class B final:public A{
void f() final {}
};
int main() {
system("chcp 65001");
A* pa=new B;
cout<<"类型A:"<< typeid(A).name()<<endl;
cout<<"类型A*:"<< typeid(A*).name()<<endl;
cout<<"类型B:"<< typeid(B).name()<<endl;
cout<<"类型B*:"<< typeid(B*).name()<<endl;
cout<<endl<<"A* pa=new B:"<<typeid(pa).name();
B* b= dynamic_cast<B*>(pa);
cout<<endl<<"dynamic_cast<B*>(pa):"<< typeid(b).name();
B object_b;
A& reference_a=object_b;
cout<<endl<<"reference_a=object_b:"<< typeid(reference_a).name();
A& reference_a_upcast= dynamic_cast<A&>(object_b);
cout<<endl<<"dynamic_cast<A&>(object_b):"<< typeid(reference_a_upcast).name();
return 0;
}
运行结果:
Active code page: 65001 类型A:1A 类型A _:P1A 类型B:1B 类型B_:P1B
A* pa=new B:P1A dynamic_cast<B*>(pa):P1B reference_a=object_b:1B dynamic_cast<A&>(object_b):1B
结果说明:
指针对象的类型识别基于被操作的左值
引用对象的运行时类型识别基于底层的实际值。
上面没有测试非virtual类的静态类型识别。