当前位置:首页 > 资讯 > 正文

研究了一波RTTI,你会了吗

研究了一波RTTI,你会了吗

研究了一波RTTI,你会了吗

最近研究了一波RTTI,整理了一下知识点,在这里分享一下,下面是目录:

RTTI 是 Run Time Type Information 的缩写,从字面上来理解就是运行时期的类型信息,它的主要作用就是动态判断运行时期的类型。

一般在dynamic_cast和typeid中用到,例如父类B的指针转换子类A的指针,dynamic_cast会判断B究竟是不是A的父类,如果不是,会返回nullptr,相对于强转会更加安全。依据什么判断的呢?就是RTTI。

先看下面这段代码:

结果如下:

上面的代码是正常的一段使用多态的代码,同时也包含了子类指针转基类指针,基类指针转子类指针,从输出结果中可以看到,使用dynamic_cast进行不合理的基类子类指针转换时,会返回nullptr,而强转则不会返回nullptr,运行时肯定就会出现奇奇怪怪的错误,比较难排查。

如果在编译时加上-fno-rtti会怎么样?结果是这样:

可以看到,加上了-fno-rtti编译时,使用typeid或dynamic_cast会报错,即添加-fno-rtti编译会禁止我们使用dynamic_cast和typeid。那为什么要禁止使用他们呢?

RTTI的空间成本非常高:每个带有vtable(至少一个虚拟方法)的类都将获得RTTI信息,其中包括类的名称及其基类的信息。此信息用于实现typeid运算符以及dynamic_cast。(大小问题大家可以自己编写代码验证一下)

速度慢,运行时多判断了一层,性能肯定更慢一些。

tips:我这里又将typeid和dynamic_cast去掉重新编译,结果表明添加了-fno-rtti,还是可以正常使用多态,所以大家不用担心rtti的禁用会影响多态的使用。

都知道RTTI信息是存在于虚函数表中,而添加-fno-rtti后代表禁止了RTTI,那虚函数表中还会有rtti信息吗?

我这里使用clang的命令查看一下虚函数表: