• <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久久国产热无码精品免费| 精品人妻久久久久久888| 日本免费久久久久久久网站| 国产亚洲精午夜久久久久久| 亚洲日韩欧美一区久久久久我 | 久久人人爽人人爽人人片AV麻豆 | 一级做a爰片久久毛片毛片| 狠狠色综合网站久久久久久久高清| 久久久久高潮毛片免费全部播放| 精品国产一区二区三区久久| 久久综合九色综合久99| 久久午夜伦鲁片免费无码| 精品久久综合1区2区3区激情| 久久精品国产男包| 日本一区精品久久久久影院| 人妻中文久久久久| 国产精品久久久久久久久| 日本欧美国产精品第一页久久| 久久精品毛片免费观看| 国产亚洲美女精品久久久| 欧美大香线蕉线伊人久久| 久久久久久噜噜精品免费直播| 人妻少妇久久中文字幕一区二区 | 国内精品久久久久久久影视麻豆| 97视频久久久| 久久久久九九精品影院| AV色综合久久天堂AV色综合在| 亚洲欧洲中文日韩久久AV乱码| 色综合久久久久| 色婷婷综合久久久久中文一区二区| 久久精品成人欧美大片| 久久精品亚洲中文字幕无码麻豆| 无码人妻少妇久久中文字幕| 久久久国产精品网站| 午夜精品久久久久久久| 久久精品久久久久观看99水蜜桃 | 精品久久久久中文字幕一区| 麻豆成人久久精品二区三区免费|