- 作者: 雪山肥鱼
- 时间:20210912 11:41
- 目的: 了解RTTI
何为RTTI
class Base
{
public:
virtual void f()
{
cout << "Base::f()" << endl;
}
virtual void g()
{
cout << "Base::g()" << endl;
}
virtual void h()
{
cout << "Base::h()" << endl;
}
virtual ~Base()
{
}
};
class Derive :public Base
{
public:
virtual void g()
{
cout << "Derive::g()" << endl;
}
void mySelfFunc()
{
}
virtual ~Derive()
{
}
};
int main(int argc, char **argv)
{
Base *pb = new Derive();
pb->g();
Derive mydrive;
Base &yb = mydrive;
yb.g();
//c++ 运行时类型识别 RTTI,父类中必须有虚函数,父类中无虚函数,则RTTI 无意义。
//RTTI 可以在执行期间查询一个多态指针,或者多态引用的信息
//RTTI 可以靠 typeid 和 dynamic_cast 运算符体现
cout << typeid(*pb).name() << endl;// class::deirve
cout << typeid(yb).name() << endl; // class::derive
Derive *pderive = dynamic_cast<Derive*>(pb);
if (pderive != NULL)
{
cout << "pb 实际是一个 derive* 类型" << endl;
pderive->mySelfFunc();
}
return 0;
}
RTTI,运行时类型识别。实现的要求就是必须存在虚函数,也就是说一定要有虚函数表。
没有虚表,则RTII毫无意义啦
RTTI 可以在执行期间查询一个多态指针或者多态引用的信息
RTTI 体现在 :
- typeid(指针/引用).name()
- dynamic_cast<Class>(Point/Ref)
RTTI与type_info
typieid(P/R)返回的是一个常量对象的引用,这个对象的类型是 type_info, 对象的所有信息存在于 type_info 这个类中。
class Base
{
public:
virtual void f()
{
cout << "Base::f()" << endl;
}
virtual void g()
{
cout << "Base::g()" << endl;
}
virtual void h()
{
cout << "Base::h()" << endl;
}
virtual ~Base()
{
}
};
class Derive :public Base
{
public:
virtual void g()
{
cout << "Derive::g()" << endl;
}
void mySelfFunc()
{
}
virtual ~Derive()
{
}
};
int main(int argc, char **argv)
{
Base *pb = new Derive();
pb->g();
Derive mydrive;
Base &yb = mydrive;
yb.g();
//RTTI 实现原理
// typeid 返回的是一个常量对象的引用,这个对象类的信息多存在于 type_info这个类中
const type_info &tp = typeid(*pb);
//只能读,不能写
Base *pb2 = new Derive();
const type_info &tp2 = typeid(*pb2);
if (tp == tp2)
{
cout << "same class type" << endl;
}
//其他用法:
//静态类型
cout << typeid(int).name() << endl;
cout << typeid(Base).name() << endl;
cout << typeid(Derive).name() << endl;
Derive *pb3 = new Derive();
cout << typeid(pb3).name() << endl;
//动态:
cout << typeid(*pb).name() << endl;//class Derive
cout << typeid(yb).name() << endl;//class Derive
Base * pb4 = new Derive();
const type_info &tp3 = typeid(*pb4);
return 0;
}
静态: 常规类型 与 不带多态的类型判断
动态: 引入多态后, 可以判断出父类指针所指向的对象是子类. 自动识别多态,多继承中也能识别出指向的子类
如果没有虚函数,则全是 class Base,RTTI失效,就是指针的静态类型
typeinfo 保存位置
const std::type_info &tp2 = typeid(*pb2);
eax, dwrod ptr [pb2]
eax
__RTtypeid(010A158Ch)
esp, 4
dword ptr [tp2], eax
对应的汇编代码,重点看下 __RTtypeid,仅在虚函数表出现的情况,才有这个东东。

rtti相关信息在虚函数往上的4个字节。
点到为止,了解到这里就够了。
vptr,vtbl,rtti的type info 构造时机
除了vptr 是运行时子对象的构造函数中生成的,其他都是编译后就存在的,只要不重新编译生成项目,地址不变
网友评论