项目中遇到了 RTTI 先学一部分 c++ primer内容
-
运行时类型识别:
程序可以使用基类的指针或者引用来检索这些指针或引用所指对象的实际派生类型
标准库提供了两个操作符:
1. typeid 他可以返回指针或者引用所指向对象的实际类型
2. dynamic_cast 将基类类型的指针或引用安全的转为派生类的指针或者引用
对于不带虚函数的类在编译时期执行,否则在运行期间执行
使用时机:
基类指针调用派生类成员函数的话,一般应使用虚函数,这样编译器会根据对象的实际类型来选择正确的函数。但是某些情况下无法使用虚函数,那么此
时如果需要使用基类指针调用派生类成员函数便需要使用RTTI强制转换,而且必须检查转换是否成功了
(一) Dynamic_cast
dynamic_cast 如果转换到指针失败则返回 0 如果转换到引用类型失败则抛出 bad_cast 异常
对指针操作:
if(Derived *derivedPtr = dynamic_cast<Derived*> (basePtr)){
//basePtr point to a derived object;
}else{
//basePtr point to a base object;
}
在 if 语句中进行检查 1.条件代码内部知道 derivedPtr 的类型 2.不可能在测试代码和使用代码中加入代码,也就是说不会在没有测试前就使用derivedPtr 3.如果失败外部不会使用未绑定的指针derivedPtr
对引用操作:
因为不存在空引用所以转换失败抛出异常
void f(const Base& b){
try{
const Derived &d = dynamic_cast<const Derived&> (b);
}catch(bad_cast){
}
}
(二) typeid
typeid(e) e是任意的表达式或者类型名
Base *bp;
Derived *dp;
//compare type at run time of two objects
if(typeid(*bp)==typeid(*dp)){
//bp dp point to objects of the same type
}
if(typeid(*bp)==typeid(Derived)){
//bp actually point to a Derived
}
注意typeid 测试的是 *bp 对象
//test always fails: The type of bp if pointer to Base
if(typeid(bp)==typeid(Derived)){
}
Base* 将永远和Derived类型不同
只有typeid 的操作数是带虚函数的类的对象的时候,才返回动态类型信息,测试指针返回指针的静态的,编译时类型
(三 )type_info 类
作为typeid的返回值 提供
t1==t2 t1!=t2 t.name() 的操作
作为应用例子,可以实现一个类型敏感的相等操作符
friend bool operator == (const base& lhs, const base& rhs){
return typeid(lhs)==typeid(rhs) && lhs.equal(rhs);
}
这样可以处理基类子类混合的相等判断了