C++ 编程思想——运行时类型识别

RTTI的两种使用方法:
1. 第一种是typeid(),它很像sizeof,看上去像一个函数,但实际上它是由编译器实现的。
    typeid()的参数是一个对象引用或者指针,返回全局typeinfo类的常量对象的一个引用。可以用==或者!=来互相比较这些对象。
    ISO C++标准并没有确切定义typeinfo,它的确切定义编译器相关的,但是标准却规定了其实现必需提供如下四种操作:

 typeinfo1 == typeinfo2  如果两个对象typeinfo1和typeinfo2类型相同,则返回true;否则返回false
 typeinfo1 != typeinfo2  如果两个对象typeinfo1和typeinfo2类型不同,则返回true;否则返回false
 typeinfo.name()  可以使用name()来获得类型的名称。例如:cout << typeid(*s).name()
 typeinfo1.before(t2)  可以使用before(typeinfo&)来查询一个typeinfo对象是否在另一个typeinfo对象的前面(按照继承顺序

    当typeid操作符的操作数是不带有虚函数的类类型时,typeid操作符会指出操作数的类型,而不是底层对象的类型。
    如果typeid操作符的操作数是至少包含一个虚拟函数的类类型时,并且该表达式是一个基类的应用,则typeid操作符指出底层对象的派生类类型。

    typeid可以运用于非多态类型,但这种方法获得的信息是值得怀疑的。

2. 第二种是“dynamic_cast安全类型向下映射”
    可以使用C++的静态映射static_cast强制执行,但这样做很危险,因为没有办法明确地知道它实际上是什么。
    所以使用dynamic_cast
    shape* sp = new circle;
    circle* cp = dynamic_cast<circle*>(sp);
    if (cp) cout << "cas successful";             // 如果返回一个地址,成功;返回null,说明它不是一个circle* 对象。

动态映射不仅可以用来确定准确的类型,也可用于多层次继承关系中的中间类型。
typeid总是产生一个typeinfo对象的引用来描述一个对象的准确类型,因此它不会给出中间层次的信息。
typeid看到的指针类型是基类,而它看到的引用类型则是派生类。
typeid看到的指针指向的类型是派生类,而它看到的引用的地址类型则是基类。
多重继承的时候,如果将一个实际指向子类的基类指针做强制转换成子类指针也会出错。

------------------------------两种Bad-cast-----------------------------------
1. dynamic_cast转换一个完全不相关的类
2. typeid操作一个空指针

------------------------------其它语法-----------------------------------
static_cast : 为了“行为良好”和“行为较好”而使用的映射,包括一些我们可能现在不用的映射(如向上映射和自动类型转换)。
const_cast :用于映射常量和变量(const和volatile)
reinterpret_cast:为了映射到一个完全不同的意思。这是所有映射中最危险的。

原文链接: https://www.cnblogs.com/makesunny/archive/2012/12/10/2811401.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++ 编程思想——运行时类型识别

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/72027

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午3:10
下一篇 2023年2月9日 下午3:10

相关推荐