• <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>
            隨筆 - 1, 文章 - 9, 評(píng)論 - 4, 引用 - 0
            數(shù)據(jù)加載中……

            vft、vptr、thunk

            對(duì)于vft(vitrual function table或是vitrual method table)和vptr(vitrual pointer)做一些總結(jié)。

            當(dāng)類(lèi)中有虛函數(shù)的時(shí)候才會(huì)建立vft,這個(gè)表里面按照順序(從0開(kāi)始)和類(lèi)里面的虛函數(shù)做出對(duì)應(yīng)。
            如果一個(gè)類(lèi)里面有虛函數(shù)(就是有vft),那它就有個(gè)vptr。vptr是一個(gè)存在在類(lèi)中的一個(gè)隱含指針,這個(gè)指針指向的是vft這個(gè)表。
            當(dāng)調(diào)用類(lèi)中的某個(gè)虛函數(shù)的時(shí)候,就通過(guò)這個(gè)指針去找vft里面對(duì)應(yīng)的函數(shù),然后拿來(lái)調(diào)用。

            class Base
            {
            public:
                FunctionPointer 
            *__vptr;
                
            virtual void function1() {};
                
            virtual void function2() {};
            };

            class D1: public Base
            {
            public:
                
            virtual void function1() {};
            };

            class D2: public Base
            {
            public:
                
            virtual void function2() {};
            };

            這里顯示的把vptr顯示出來(lái),但實(shí)際上是看不見(jiàn)的。


            注意d1和d2的vptr是繼承自base的

            int main()
            {
                D1 cClass;
                Base *pClass = &
            cClass;
                pClass->function1();
            }

            上面的代碼之所以可以執(zhí)行,是因?yàn)椋簆Class指針指向的僅僅是cClass中屬于Base的部分(因?yàn)锽ase是D1的父類(lèi)),因?yàn)関ptr原本是在Base中的(雖然看不見(jiàn)),所以pClass是可以調(diào)用vptr的。再由于繼承的關(guān)系,此時(shí)的vptr處于D1類(lèi)中,它指向的是D1的vft,所以pClass->funtion1()這句可以執(zhí)行成功。

            說(shuō)一個(gè)復(fù)雜的情況:

            class A
            {
            public:
                
            virtual void a();
            };

            class B : public A
            {
            public:
                
            virtual void a();
                
            virtual void c();
                
            virtual void f();
            };

            class C : public A
            {
            public:
                
            virtual void e();
            };

            class D : public B, public C
            {
            public:
                
            void a();
                
            void g();
            }:

            這里就有點(diǎn)問(wèn)題,如果單純的vft中按照函數(shù)順序的話。在D這個(gè)類(lèi)中,來(lái)自B和來(lái)自C這兩個(gè)類(lèi)中的B::c函數(shù)和C::e函數(shù)在他們的類(lèi)中所在的位置從文本上看都是第二的位置(C類(lèi)還有個(gè)A中繼承的a函數(shù))。那么對(duì)于D來(lái)說(shuō)有同一個(gè)位置有兩個(gè)函數(shù),這時(shí)vft必然不能正常實(shí)現(xiàn)。在C++中其實(shí)D這個(gè)類(lèi)有兩個(gè)vft,一個(gè)基于B建立,一個(gè)基于C建立。當(dāng)然這種情況下只有在多繼承時(shí)才出現(xiàn)。

            那么在實(shí)際運(yùn)行時(shí),首先要把vft的地址(也就是vptr的值)放到寄存器里面,然后要確定用的是哪個(gè)類(lèi)的vft(對(duì)于D這個(gè)類(lèi)來(lái)說(shuō)),接著再索引這個(gè)函數(shù)表找到函數(shù),最后才根據(jù)地址執(zhí)行函數(shù)。

            也就只對(duì)于多繼承這種復(fù)雜的情況下,才有上面這么多步驟。對(duì)于單繼承,只用找到表,找到索引,找到函數(shù),調(diào)用即可。GCC的thunk在建立vft的時(shí)候就確定了到底這個(gè)函數(shù)是在哪個(gè)對(duì)象

            load [object_reg+#VFToffset], table_reg
            load [table_reg
            +#deltaOffset], delta_reg
            load [table_reg
            +#numOffset], method_reg
            add object_reg, delta_reg, object_reg
            call method_reg

            上面的匯編取自一篇論文,VFToffset就是vft的地址偏移,deltaOffset就是多繼承產(chǎn)生的偏移(選哪個(gè)類(lèi),B還是C),numOffset就是函數(shù)偏移。省去的就是2、4這兩條語(yǔ)句,thunk把這步做了。

            關(guān)于thunk還是有點(diǎn)問(wèn)題,不是非常明白。

            posted on 2008-12-19 18:09 EiN 閱讀(541) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): C/C++ and ASM

            精品久久久久中文字幕日本| 性做久久久久久久久浪潮| 国产一级做a爰片久久毛片| 国产亚洲精久久久久久无码| 国产精品成人无码久久久久久| 久久亚洲日韩看片无码| 青青青国产成人久久111网站| 午夜精品久久久久| 中文字幕亚洲综合久久2| 久久久久久精品久久久久| 国产高清国内精品福利99久久| 亚洲国产精品无码久久久蜜芽| 久久婷婷五月综合色99啪ak| 国产精品久久久久久一区二区三区| 热久久视久久精品18| 久久99精品国产99久久6| 久久久久人妻精品一区| 久久人人爽人人爽人人av东京热| 国产精品美女久久久久AV福利| 久久99热只有频精品8| 伊人久久精品无码av一区| 久久人人爽人人爽人人片AV东京热 | 四虎国产永久免费久久| 久久综合国产乱子伦精品免费| 亚洲伊人久久成综合人影院 | 久久精品中文字幕第23页| 高清免费久久午夜精品| 久久天天躁狠狠躁夜夜96流白浆| 亚洲精品无码久久毛片| 青青草原综合久久大伊人导航 | 国产L精品国产亚洲区久久| 久久综合香蕉国产蜜臀AV| 伊人久久大香线蕉精品不卡| 精品久久综合1区2区3区激情| 国产精品久久久天天影视| 久久99精品国产一区二区三区| 欧美一区二区三区久久综 | 久久综合色之久久综合| 久久天天躁狠狠躁夜夜不卡| 久久婷婷五月综合色奶水99啪| 亚洲人成精品久久久久|