• <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>
            posts - 195,  comments - 30,  trackbacks - 0

            在《深度探索C++對象模型》里,有一個問題,也是去公司面試的時候那些技術(shù)人員常問的問題:在C++中,obj是一個類的對象,p是指向obj的指針,該類里面有個數(shù)據(jù)成員mem,請問obj.mem和p->mem在實(shí)現(xiàn)和效率上有什么不同。


            答案是:只有一種情況下才有重大差異,該情況必須滿足以下3個條件:

            (1)、obj 是一個虛擬繼承的派生類的對象
            (2)、mem是從虛擬基類派生下來的成員
            (3)、p是基類類型的指針

            當(dāng)這種情況下,p->mem會比obj.mem多了兩個中間層。(也就是說在這種情況下,p->mem比obj.mem要明顯的慢,呵呵)

            WHY?

            如果好奇心比較重的話,請往下看 :)


            1、虛基類的使用,和為多態(tài)而實(shí)現(xiàn)的虛函數(shù)不同,是為了解決多重繼承的二義性問題。

            舉例如下:

            class A
            {
            public:
                int a;
            };

            class B : virtual public A
            {
            public:
               int b;
            };

            class C :virtual public A
            {
            public:
               int c;
            };

            class D : public B, public C
            {
            public:
               int d;
            };

            上面這種菱形的繼承體系中,如果沒有virtual繼承,那么D中就有兩個A的成員int a;繼承下來,使用的時候,就會有很多二義性。而加了virtual繼承,在D中就只有A的成員int a;的一份拷貝,該拷貝不是來自B,也不是來自C,而是一份單獨(dú)的拷貝,那么,編譯器是怎么實(shí)現(xiàn)的呢??

            在回答這個問題之前,先想一下,sizeof(A),sizeof(B),sizeof(C),sizeof(D)是多少?(在32位x86的linux2.6下面,或者在vc2005下面)

            在linux2.6下面,結(jié)果如下:sizeof(A) = 4; sizeof(B) = 12; sizeof(C) = 12; sizeof(D) = 24

            sizeof(B)為什么是12呢,那是因?yàn)槎嗔艘粋€指針(這一點(diǎn)和虛函數(shù)的實(shí)現(xiàn)一樣),那個指針是干嘛的呢?

            那么sizeof(D)為什么是24呢?那是因?yàn)槌死^承B中的b,C中的c,A中的a,和D自己的成員d之外,還繼承了B,C多出來的2個指針(B和C分別有一個)。再強(qiáng)調(diào)一遍,D中的int a不是來自B也不是來自C,而是另外的一份從A直接靠過來的成員。

            如果聲明了D的對象d: D d;
            那么d的內(nèi)存布局如下:

            vb_ptr: 繼承自B的指針
             
            int b: 繼承自B公有成員
             
            vc_ptr:繼承自C的指針
             
            int c: 繼承自C的共有成員
             
            int d: D自己的公有成員
             
            int a: 繼承自A的公有成員
             


            那么以下的用法會發(fā)生什么事呢?

            D dD;
            B *pb = &dD;
            pb->a;

            上面說過,dD中的int a不是繼承自B的,也不是繼承自C的,那么這個B中的pb->a又會怎么知道指向的是dD內(nèi)存中的第六項(xiàng)呢?

            那就是指針vb_ptr的妙用了。原理如下:(其實(shí)g++3.4.3的實(shí)現(xiàn)更加復(fù)雜,我不知道是出于什么考慮,而我這里只說原理,所以把過程和內(nèi)容簡單化了)

            首先,vb_ptr指向一個整數(shù)的地址,里面放的整數(shù)是那個int a的距離dD開始處的位移(在這里vb_ptr指向的地址里面放的是20,以字節(jié)為單位)。編譯器是這樣做的:

            首先,找到vb_ptr(這個不用找,因?yàn)樵趃++中,vb_ptr就是B*中的第一項(xiàng),呵呵),然后取得vb_ptr指向的地址的內(nèi)容(這個例子是20),最后把這個內(nèi)容與指針pb相加,就得到pb->a的地址了。

            所以說這種時候,用指針轉(zhuǎn)換多了兩個中間層才能找到基類的成員,而且是運(yùn)行期間。

            由此也可以推知dD中的vb_ptr和vc_ptr的內(nèi)容都是一樣的,都是指向同一個地址,該地址就放20(在本例中)

            如下的語句呢:

            A *pa = &dD;
            pa->a = 4;

            這個語句不用轉(zhuǎn)換了,因?yàn)榫幾g器在編譯期間就知道他把A中的成員插在dD中的那個地方了(在本例中是末尾),所以這個語句中的運(yùn)行效率和dD.a是一樣的(至少也是差不多的)

            這就是虛基類實(shí)現(xiàn)的基本原理。

            注意的是:那些指針的位置和基類成員在派生類成員中的內(nèi)存布局是不確定的,也就是說標(biāo)準(zhǔn)里面沒有規(guī)定int a必須要放在最后,只不過g++編譯器的實(shí)現(xiàn)而已。c++標(biāo)準(zhǔn)大概只規(guī)定了這套機(jī)制的原理,至于具體的實(shí)現(xiàn),比如各成員的排放順序和優(yōu)化,由各個編譯器廠商自己定~


            本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/jiangnanyouzi/archive/2009/01/06/3721091.aspx

            posted on 2011-03-07 15:39 luis 閱讀(271) 評論(0)  編輯 收藏 引用

            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            <2011年3月>
            272812345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            文章分類

            文章檔案

            友情鏈接

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久久久免费视频| 国产成人久久激情91| 国产精品免费久久久久电影网| 久久九九久精品国产免费直播| 欧美大战日韩91综合一区婷婷久久青草 | 久久人妻少妇嫩草AV无码蜜桃| 香港aa三级久久三级老师2021国产三级精品三级在 | 久久中文字幕无码专区| 久久精品成人欧美大片| 热re99久久精品国产99热| 国内精品伊人久久久影院 | 一本色道久久99一综合| 久久综合久久综合九色| 国产成人精品综合久久久久 | 久久久久国产精品人妻| 一本伊大人香蕉久久网手机| 四虎国产精品成人免费久久| 成人精品一区二区久久久| 久久精品一本到99热免费| 麻豆av久久av盛宴av| 丰满少妇人妻久久久久久4| 亚洲中文久久精品无码| 一本色道久久88综合日韩精品 | 久久99国产亚洲高清观看首页| 国产毛片欧美毛片久久久| 欧美久久久久久| 欧美色综合久久久久久| 久久精品国产精品亚洲艾草网美妙| 亚洲国产精品无码久久一区二区 | 久久www免费人成精品香蕉| 国产精品美女久久久| 97久久久久人妻精品专区 | 伊人久久精品影院| 欧美久久综合九色综合| 久久久99精品成人片中文字幕| AAA级久久久精品无码区| 国产成人无码精品久久久久免费| 国产91色综合久久免费分享| a高清免费毛片久久| 蜜桃麻豆www久久| 亚洲一区中文字幕久久|