• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            統(tǒng)計(jì)

            • 隨筆 - 50
            • 文章 - 42
            • 評(píng)論 - 147
            • 引用 - 0

            留言簿(6)

            隨筆分類(lèi)

            文章分類(lèi)

            Link

            搜索

            •  

            積分與排名

            • 積分 - 164627
            • 排名 - 159

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            對(duì)象與對(duì)象的類(lèi)型信息----獲取對(duì)象的RTTI信息

            夢(mèng)在天涯 在上篇文章里問(wèn)可不可以研究下對(duì)象與對(duì)象的類(lèi)型信息怎么聯(lián)系起來(lái)的,就是當(dāng)調(diào)用dynamic_cast的時(shí)候?yàn)槭裁茨軌蛘_的識(shí)別對(duì)象的類(lèi)型

            RTTI(Run Time Type Identification)運(yùn)行時(shí)類(lèi)型識(shí)別是有編譯器在編譯器生成的特殊類(lèi)型信息,包括對(duì)象繼承關(guān)系,對(duì)象本身的描述,RTTI是為多態(tài)而生成的信息,所以只有具有虛函數(shù)的對(duì)象在會(huì)生成

            那RTTI在哪里呢?
            MSVC編譯器在vftable前設(shè)置了一個(gè)指針,指向叫做“Complete Object Locator”(完整對(duì)象定位器)的結(jié)構(gòu)。這樣稱(chēng)呼是因?yàn)樗试S編譯器從特定的vftable指針(因?yàn)橐粋€(gè)類(lèi)可能有若干vftable)找到完整對(duì)象的位置。COL就像如下定義:

            請(qǐng)看如下代碼:

              1#include "iostream"
              2#include "string"
              3
              4
              5using namespace std;
              6class Aclass
              7{
              8public:
              9     int a;
             10    virtual void setA(int tmp)
             11    {
             12        a=tmp;
             13        cout<<a<<endl;
             14    }

             15}
            ;
             16class Bclass:public Aclass
             17{
             18public:
             19    virtual void setA(int tmp)
             20    {
             21        a=tmp+10;
             22        cout<<a<<endl;
             23    }

             24public:
             25    void print()
             26    {
             27        cout<<a<<endl;
             28    }

             29}
            ;
             30class Cclass:public Bclass
             31{
             32}
            ;
             33typedef unsigned long DWORD;
             34struct TypeDescriptor
             35{
             36    DWORD ptrToVTable;
             37    DWORD spare;
             38    char name[8];
             39}
            ;
             40struct PMD
             41{
             42
             43    int mdisp;  //member displacement
             44
             45    int pdisp;  //vbtable displacement
             46
             47    int vdisp;  //displacement inside vbtable
             48
             49}
            ;
             50struct RTTIBaseClassDescriptor
             51
             52{
             53
             54    struct TypeDescriptor* pTypeDescriptor; //type descriptor of the class
             55
             56    DWORD numContainedBases; //number of nested classes following in the Base Class Array
             57
             58    struct PMD where;        //pointer-to-member displacement info
             59
             60    DWORD attributes;        //flags, usually 0
             61
             62}
            ;
             63
             64struct RTTIClassHierarchyDescriptor
             65{
             66
             67    DWORD signature;      //always zero?
             68
             69    DWORD attributes;     //bit 0 set = multiple inheritance, bit 1 set = virtual inheritance
             70
             71    DWORD numBaseClasses; //number of classes in pBaseClassArray
             72
             73    struct RTTIBaseClassArray* pBaseClassArray;
             74
             75}
            ;
             76
             77struct RTTICompleteObjectLocator
             78
             79{
             80
             81    DWORD signature; //always zero ?
             82
             83    DWORD offset;    //offset of this vtable in the complete class
             84
             85    DWORD cdOffset;  //constructor displacement offset
             86
             87    struct TypeDescriptor* pTypeDescriptor; //TypeDescriptor of the complete class
             88
             89    struct RTTIClassHierarchyDescriptor* pClassDescriptor; //describes inheritance hierarchy
             90
             91
             92}
            ;
             93
             94
             95int _tmain(int argc, _TCHAR* argv[])
             96{
             97    Aclass* ptra=new Bclass;
             98    int ** ptrvf=(int**)(ptra);
             99    RTTICompleteObjectLocator str=
            100        *((RTTICompleteObjectLocator*)(*((int*)ptrvf[0]-1)));
            101    //abstract class name from RTTI
            102    string classname(str.pTypeDescriptor->name);
            103    classname=classname.substr(4,classname.find("@@")-4);
            104    cout<<classname<<endl;
            105    system("pause");
            106    return 0;
            107}

            108

            輸出結(jié)果:


            在RTTI運(yùn)行時(shí)結(jié)構(gòu)體中包含許多豐富的信息,甚至我們可以利用一個(gè)實(shí)例的RTTI信息去復(fù)原整個(gè)類(lèi)繼承圖譜

            而對(duì)于dynamic_cast也是利用這個(gè)信息來(lái)準(zhǔn)確的識(shí)別實(shí)例所對(duì)應(yīng)的類(lèi)型,不過(guò)如果對(duì)于沒(méi)有多態(tài)的實(shí)例,dynamic_cast所做的也只是和編譯器類(lèi)型轉(zhuǎn)換一樣的事情,僅僅是通過(guò)類(lèi)型和繼承關(guān)系進(jìn)行轉(zhuǎn)換,還是看例子吧:

             1class mother
             2{
             3    int a;
             4    int b;
             5}
            ;
             6class father
             7{
             8    double c;
             9}
            ;
            10class son:public mother,public father
            11{
            12    char a;
            13    short c;
            14}
            ;
            15
            16int _tmain(int argc, _TCHAR* argv[])
            17{
            18    mother* m=new son();
            19    father* f=dynamic_cast<father*>(m);
            20    system("pause");
            21    return 0;
            22}
            運(yùn)行會(huì)得到以下錯(cuò)誤:
            error C2683: “dynamic_cast”:“mother”不是多態(tài)類(lèi)型
            修改如下
            class mother
            {
             int a;
             int b;
             virtual void fun()
             {
             }
            };
            一切正常

            就說(shuō)這么多吧,歡迎多交流

            posted on 2009-03-12 17:55 pear_li 閱讀(4207) 評(píng)論(3)  編輯 收藏 引用 所屬分類(lèi): C++

            評(píng)論

            # re: 對(duì)象與對(duì)象的類(lèi)型信息----獲取對(duì)象的RTTI信息 2009-03-12 21:32 夢(mèng)在天涯

            超好啊,原來(lái)真的在前面啊,看到C++對(duì)象模型說(shuō)的,但是我確實(shí)是沒(méi)有想到原來(lái)是在VTable - 1啊!

            # re: 對(duì)象與對(duì)象的類(lèi)型信息----獲取對(duì)象的RTTI信息 2009-03-13 00:19 pear_li

            @夢(mèng)在天涯
            呵呵,是啊,夢(mèng)在天涯的確是看了好多書(shū)啊

            # re: 對(duì)象與對(duì)象的類(lèi)型信息----獲取對(duì)象的RTTI信息 2010-08-22 00:19 tomren

            不錯(cuò),剛看到:)
            国内精品久久人妻互换| 亚洲精品国精品久久99热一| 久久综合亚洲欧美成人| 伊人伊成久久人综合网777| 久久久久亚洲AV成人网人人网站| 国产精品美女久久久久久2018 | 丁香色欲久久久久久综合网| 久久国产成人午夜AV影院| 国产精品99久久精品爆乳| AAA级久久久精品无码区| 精品久久久久久久中文字幕 | 久久精品国产WWW456C0M| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 手机看片久久高清国产日韩| 久久久无码精品亚洲日韩软件| 蜜桃麻豆www久久国产精品| 亚洲日韩欧美一区久久久久我| 亚洲欧美成人久久综合中文网 | 国产精品99久久久久久猫咪 | 欧美久久亚洲精品| 伊色综合久久之综合久久| 一本一本久久a久久精品综合麻豆| 久久无码中文字幕东京热| 国产亚洲精久久久久久无码| 亚洲国产成人久久精品动漫| 久久国产精品二国产精品| 欧美国产成人久久精品| 久久99国产精一区二区三区| 久久国产视屏| 久久久老熟女一区二区三区| 久久99国产精品久久久| 伊人 久久 精品| 四虎国产精品免费久久5151| 亚洲国产成人精品91久久久 | 91精品免费久久久久久久久| 亚洲一级Av无码毛片久久精品| AV无码久久久久不卡蜜桃| 久久久久国产| 久久久久久狠狠丁香| 色狠狠久久综合网| 久久996热精品xxxx|