RTTI:运行阶段类型识别(Runtime Type Identification)。为啥要有这个呢,主要还是因为:基类的指针允许指向派生类对象。
这就导致一个问题:一个基类的指针,运行时,你不知道它指向的到底是基类对象,还是派生类对象。所以,有了运行时类型识别(RTTI)这个概念。
为啥需要知道是指向基类还是派生类?因为假如要用这个指针去调用一个方法(假如叫A方法),派生类才有A方法,基类没有A方法。如果不能确定它是派生类的对象时,冒然调用这个A可能导致错误。(至于为啥要让基类的指针去指向派生类对象呢?因为这是有好处的,至于啥好处,简单说就是结合虚函数使用,在基类和派生类之前调用虚方法会很方便,能自动调用基类或派生类方法)。
RTTI实现原理:
dynamic_cast:
使用dynamic_cast运算符(这个运算符是一串字母,和我们平时认识的+-x/运算符有点不一同)。
使用方法:
type_A *pa;
pa = dynamic_cast<type_A *> (p);
dynamic_cast的作用就是问下一指针p一下能否安全的转换为type_A类型的指针。如果可以,就返回一个指针为pa。否则就返回一个0(空指针)。这样加个if判断 一下,就能确定是要的类型。避免类型不对,调用方法出错。
这里,延伸出两个运算符:
typeid和typeinfo。
typeid<a>返回一个typeinfo对象的引用(即:&typeinfo)。a是一个类名或者对象。
typeinfo是一个结构,存储对象的类型信息。typeinfo重载了==和!=。
结合typeid和typeinfo。就可以判断两个对象是不是类型相同。
比如:
class A;
class B:public A;
typeid(A)==typeid(B);这个语句会返回fasle。因为A!=B类。
const_cast:
将一个本来被const限制的指针,变为没有const限制。
比如:
int A=10;//不能定义为const int A=10;这样定义,即使用了下面说的方法,也不一定起作用)
const int *p_con = &A;//此时p_con是不能修复A的值的。
int *p;
p=const_const<int *>(p_con);//此时,p可以修改A的值。初一看,这个转换感觉有点傻,还不如直接定义一个指针重新将A的地址赋给他。实际上,这个方法常用在函数时在,如果p_con是函数传入的形参。一般用const限制它不能修改传入的数据。这时很想改,那就用const_cast去改。)
*p=20;//p修改了A。
static_cast:
将一个类型强制转换为别一种类型。(此处的static不是指转换为静态,只是转换名这么叫,不要混淆)。
int b;
double c;
c=static_cast<double>(b);将b值强制转换为double类型。
这种转换和
c=double(b)这种普通的类型转换有啥区别?传说是用static_cast要安全一些,只允许能转换的才转换,不能转的类型不让转。
这里举的转换例子比较简单。还可以转类,指针等。指针转换可能复杂些,容易出错,可能能体现出static_cast的优势。
C++难,一个方面是有很多的概念,不好记,而且有些还很难理解领悟。
最近在看apollo自动驾驶的源码,先看规划控制模块的,有同样在看源码学习的,可以一起相互交流下,有输入,有输出学起来才有效果。