C++RTTI(运行阶段类型识别)
RTTI适用于包含虚函数的类
1.3个元素
dynamic_cast运算符
typeid运算符
type_info类
dynamic_cast
有什么用?
可以用来判断指针的类型转换是否安全。如果安全,则返回类型转换后的值;如果不安全,则返回0。
什么是安全的转换?
安全的指针:
指向自身类的对象。
指向自身派生的(直接和间接)的类的对象。
通过转换后,如果符合上述的条件,就是安全的转换。
class Base {
public:
virtual ~Base(){}
};
class Derived : public Base {
};
int main(void) {
Base objb;
Derived objd;
Base *pb = dynamic_cast<Base *>(&objd);
Derived *pd = dynamic_cast<Derived *>(&objb);
cout << "pb = " << pb << endl << "pd = " << pd << endl;
return 0;
}
输出:
pb = 0053FA60
pd = 00000000
可见pb是一个基类指针,他可以指向它的派生类派生类对象,所以第一个转换时安全的;pd是一个派生类的指针,它可以指向他自身的类的对象或者它的派生类(本例中没有)的对象,pd不能指向基类的对象,所以,第二个转换是不安全的。
typeid运算符和type_info类
有什么用?
typeid接收参数(类名或结果为对象的表达式),返回一个type_info类对象的引用。
type_info在头文件typeinfo头文件中定义
type_info有一个name()成员成员函数,返回由参数的类名构成的字符串。
int main(void) {
Base objb;
Derived objd;
Base *p1 = &objb;
Base *p2 = &objd;
cout << typeid(*p1).name() << endl << typeid(*p2).name() << endl;
return 0;
}
输出:
class Base
class Derived
type_info重载了==和!=运算符;用来判断两个对象是否属于同一个类,或者判断一个对象是否是一个类的实体。
int main(void) {
Base objb;
Derived objd;
Base *p1 = &objb;
Base *p2 = &objd;
//*p1和*p2是否为同类对象
cout << (typeid(*p1) == typeid(*p2)) << endl;
//*p1和*p2是否不为同类对象
cout << (typeid(*p1) != typeid(*p2)) << endl;
//*p1是不是类Base的实例化对象
cout << (typeid(Base) == typeid(*p1)) << endl;
//*p2是不是类Base的实例化对象
cout << (typeid(Base) == typeid(*p2)) << endl;
return 0;
}
输出:
0
1
1
0