C++ 运行时类型识别(RTTI)

2021-03-08  本文已影响0人  突击手平头哥

C++ 运行时类型识别(RTTI)

C++以虚函数的形式支持了多态,某种形式上支持了运行时类型决议;但是dynamic_cast可以做到更多,在运行时对类型做出判断然后决定是否进行转换;其本质在于在虚函数表中存储了类的信息

typeid关键字和type_info类

typeid是C++中的关键字,类似于sizeof可以获取类、类实例的type_info对象的引用;需要注意的是如果表达式含有虚函数表,那么会在运行时获取表达式动态类型,否则在编译时获取表达式的静态类型

type_info接口

operator=[deleted]          //禁止拷贝
bool operator==( const type_info& rhs ) const;                  //判断是否相等
bool operator!=( const type_info& rhs ) const;                  //判断是否不等
bool before( const type_info& rhs ) const;                      //rhs类是否在出现在本类前
const char* name() const;                                       //返回类型名
#include <stdio.h>
#include <stdlib.h>
#include <typeinfo>

class Parent
{
public:
    virtual void tt(){};
};

class Son: public Parent
{

};

class Test_A {

};

class Test_B : public Test_A{

};

int main()
{
    Parent *p1 = new Son();
    Son *s1 = new Son();
    Test_A *ta = new Test_A();
    printf("ptr type Son: %s, Parent: %s, Test_A: %s\n", typeid(s1).name(), typeid(p1).name(), typeid(ta).name());
    printf("obj Son: %s, Parent: %s, Test_A: %s\n", typeid(*s1).name(), typeid(*p1).name(), typeid(*ta).name());
    printf("type Son: %s, Parent: %s, Test_A: %s\n", typeid(Son).name(), typeid(Parent).name(), typeid(Test_A).name());
    printf("successtion: %d, %d\n", typeid(Son).before(typeid(Parent)), typeid(Parent).before(typeid(Son)));

    Test_A *tb = new Test_B();
    printf("type tb: %s,\n", typeid(tb).name());


}
ptr type Son: P3Son, Parent: P6Parent, Test_A: P6Test_A
obj Son: 3Son, Parent: 3Son, Test_A: 6Test_A
type Son: 3Son, Parent: 6Parent, Test_A: 6Test_A
successtion: 1, 0
type tb: 6Test_A

dynamic_cast类型转换

dynamic_cast支持指针和引用的转换,只有存在相关性时才能够转换成功;对于指针类型,转换失败返回nullptr,对于引用类型,转换失败抛出bad_cast异常;同样时依赖于虚函数表进行的动态类型识别

class Parent
{
public:
    virtual void tt(){};
};

class Son: public Parent
{

};

class Test_A {

};

class Test_B : public Test_A{

};

int main()
{
    Parent *p1 = new Parent();
    Son *s1 = dynamic_cast<Son*>(p1);       //succ



    Test_A *ta = new Test_A();
    //Test_B *tb = dynamic_cast<Test_B*>(ta); //fail

    return 0;
}

  在虚函数表中会存储类的type_info数据,但是具体实现由编译器来进行处理;这里就不继续分析了

上一篇下一篇

猜你喜欢

热点阅读