美文网首页
C++ 运行时类型识别(RTTI)

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

作者: 突击手平头哥 | 来源:发表于2021-03-08 23:28 被阅读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
    
    • type_infoname并不是类名,但是和类名有关可以看出来
    • 类实例和类指针的类型是不一样的
    • 只有拥有虚函数,类实例才能在运行时获取真正的类型

    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数据,但是具体实现由编译器来进行处理;这里就不继续分析了

    相关文章

      网友评论

          本文标题:C++ 运行时类型识别(RTTI)

          本文链接:https://www.haomeiwen.com/subject/pvtvqltx.html