• dynamic_cast, RTTI, 整理


    主要是参考下图,了解内存布局,然后写个实例程序就差不多明白了,但是需要熟悉指针转换。

    1) 只有多态类才有RTTI信息,dynamic_cast正是运用RTTI进行转换,属于运行时类型检查。

    2) dynamic_cast判断两个指针是否能转换时,用RTTI可以知道当前实际对象,然后遍历自己所有的父类,看是否有与目标类型一致的,如果有就可以进行转换。

    3) dynamic_cast是安全的,可以通过检查返回值或异常捕捉来判断是否转成功。其中检查返回值用于指针转换,异常捕捉用于引用转换。

    4) 补充一点,与static_cast不同,即使两个类没有直接继承关系,但是只要在一个类层次结构中,就有可能指向同一个对象,也就可以进行dynamic_cast。以下图为例,C继承自A,B。A, B指针就可以进行dynamic_cast,并可能成功。

        C * pc = new C;
        A* pa = pc;
        B* pb = pc;

        pb = dynamic_cast<B*>(pa); // 可以成功进行转换,因为二者指向的都是C对象。

     下面的例子主要是关于RTTI的,打印出一个对象和她所有父类的运行时信息,这里的运行时信息主要是类的名字。

    #include "iostream"
    #include "string" 
    #include <typeinfo>
    using namespace std;
    
    
    class Zero
    {
    public:
        virtual void f111() { }
    };
    
    class Base : public Zero
    {
    public:
        virtual void f() { }
    };
    
    class Deri1234567890ve : public Base
    {
    };
    
    typedef unsigned long DWORD;
    
    struct PMD
    {
        int mdisp;  //member displacement
        int pdisp;  //vbtable displacement
        int vdisp;  //displacement inside vbtable
    };
    
    struct RTTIBaseClassDescriptor
    {
        struct TypeDescriptor* pTypeDescriptor; //type descriptor of the class
        DWORD numContainedBases; //number of nested classes following in the Base Class Array
        struct PMD where;        //pointer-to-member displacement info
        DWORD attributes;        //flags, usually 0
    };
    
    
    struct TypeDescriptor
    {
        DWORD ptrToVTable;
        DWORD spare;
        char name[ ];
    };
    
    struct RTTIClassHierarchyDescriptor
    {
        DWORD signature;      //always zero?
        DWORD attributes;     //bit 0 set = multiple inheritance, bit 1 set = virtual inheritance
        DWORD numBaseClasses; //number of classes in pBaseClassArray
        struct RTTIBaseClassArray* pBaseClassArray;
    };
    
    struct RTTICompleteObjectLocator
    
    {
    
        DWORD signature; //always zero ?
    
        DWORD offset;    //offset of this vtable in the complete class
    
        DWORD cdOffset;  //constructor displacement offset
    
        struct TypeDescriptor* pTypeDescriptor; //TypeDescriptor of the complete class
    
        //int * ptr;
        struct RTTIClassHierarchyDescriptor* pClassDescriptor; //describes inheritance hierarchy
    
    };
    
    
    
    
    int main()
    {
        /*Base *pderive = new Deri1234567890ve();
        int **ptr = (int **)(&pderive);
        int *ptable = (int *)(*(int *)(*ptr)); 
        int * rtti = ptable -1;
    
        RTTICompleteObjectLocator * RIIT_locator =   (RTTICompleteObjectLocator *)( *(int*)rtti);
        cout<<RIIT_locator->pTypeDescriptor->name<<endl;*/
    
    
        Base *pderive = new Deri1234567890ve();
        int *ptable = (int*)*(int*)pderive;
        int * rtti = ptable -1;
    
        // 显示当前类的名字“。。Deri1234567890ve。。”
    RTTICompleteObjectLocator
    * RIIT_locator = (RTTICompleteObjectLocator *)( *(int*)rtti); cout<<RIIT_locator->pTypeDescriptor->name<<endl; // 显示自己和所有父类的名字
    int * p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray); int * p2 = (int*)*(p1+2); TypeDescriptor* pDesc = (TypeDescriptor*)(*p2); cout<<"One of Base Classes: "<<pDesc->name<<endl; p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray); p2 = (int*)*(p1 + 1); pDesc = (TypeDescriptor*)(*p2); cout<<"One of Base Classes: "<<pDesc->name<<endl; p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray); p2 = (int*)*(p1); pDesc = (TypeDescriptor*)(*p2); cout<<"One of Base Classes: "<<pDesc->name<<endl; }

    参考:

    浅议 Dynamic_cast 和 RTTI   http://www.cnblogs.com/zhyg6516/archive/2011/03/07/1971898.html

    http://www.openrce.org/articles/full_view/23 

    asdfasdf

  • 相关阅读:
    java 放射机制简介
    java 放射机制简介
    后海日记(1)
    后海日记(1)
    java 发邮件 代码
    java 发邮件 代码
    hadoop学习笔记411
    hadoop学习笔记411
    swoole_table
    用swoole简单实现MySQL连接池
  • 原文地址:https://www.cnblogs.com/dirichlet/p/3221066.html
Copyright © 2020-2023  润新知