<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    so true

    心懷未來,開創未來!
    隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
    數據加載中……

    c++內存對象布局

    收藏陳皓的幾篇博文:
    http://haoel.blog.51cto.com/313033/124567
    http://haoel.blog.51cto.com/313033/124561
    http://haoel.blog.51cto.com/313033/124595

    看完上面的文章,應該可以回答一個問題:指針被強制類型轉化之后,指針的值會改變嗎?
    答案:有時候是會的。haoel把繼承分為5類,我再把它們作個標記:
    沒有虛繼承:單一繼承(1), 非重復多重繼承(2), 重復多重繼承(3);
    有虛繼承:單一繼承(4),重復多重繼承(5)。
    我先區別兩個概念“類的內存布局(由此可以計算出類的大?。?#8221;和“類本身的內存布局(由此可以計算出類本身的大?。?#8221;:
    sizeof(類)= sizeof(類本身) + sizeof(所有父類)。
    而類本身的內存布局由兩部分構成:vptr + 成員變量, 整個類的內存布局是把類本身和所有父類的內存布局拼接在一起的,注意:對于類型(1),整個類只有一個vptr,因此父類的內存布局只有成員變量了。

    拼接的規則是:先父類后子類,但特例是虛擬繼承,在虛擬繼承時,會變成“先子類后父類”,因為虛擬繼承的目的是:認為父類有common的東西,大家共享之。

    因此,vptr不一定只能出現在類內存布局的始端,準確的說: 應該是出現在各個類本身的內存布局的始端。
    當發生類型轉化時,比如要從Derived*轉化到Base*,轉化后的結果會是指向“Base這個父類自身的內存布局的始端”,一旦這個始端和“Derived類的內存布局始端“不一致,那么
    就發生了指針類型轉化后指針值的改變。
    下面是一個例子:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>

    using namespace std;

    class A {
    public:
        virtual ~A() {};
        int iA;
    };

    class A1 {
    public:
        virtual ~A1() {};
        int iA1;
    };

    class B: public A {
    public:
        virtual ~B() {};
        int iB;
    };

    class C: virtual public A {
    public:
        virtual ~C() {};
        int iC;
    };

    class D: public A, public A1 {
    public:
        virtual ~D() {};
        int iD;
    };

    int main(int argc, char* argv[]) {
        A* pa = new B();
        cout << "B size:" << sizeof(B) << endl;
        cout << "A addr:" << pa << endl;
        cout << "B addr ():" << (B*)pa << endl;
        cout << "B addr dynamic_cast:" << dynamic_cast<B*>(pa) << endl;

        cout << "-------------------------------" << endl;

        A* pa2 = new C();
        cout << "C size:" << sizeof(C) << endl;
        cout << "A addr:" << pa2 << endl;
        //cout << "C addr ():" << (C*)pa2 << endl; //compile error
        cout << "C addr dynamic_cast:" << dynamic_cast<C*>(pa2) << endl;

        cout << "-------------------------------" << endl;

        C* pc = dynamic_cast<C*>(pa2);
        cout << "C addr dynamic_cast:" << pc << endl;
        cout << "A addr ():" << (A*)pc << endl;
        cout << "A addr dynamic_cast:" << dynamic_cast<A*>(pc) << endl;

        cout << "-------------------------------" << endl;

        D* pd = new D();
        cout << "D size:" << sizeof(D) << endl;
        cout << "D addr:" << pd << endl;
        cout << "A addr ():" << (A*)pd << endl;
        cout << "A addr dynamic_cast:" << dynamic_cast<A*>(pd) << endl;
        cout << "A1 addr dynamic_cast:" << dynamic_cast<A1*>(pd) << endl;
        return 0;
    }

    結果:
    B size:16
    A addr:0x8a96010
    B addr ():0x8a96010
    B addr dynamic_cast:0x8a96010
    -------------------------------
    C size:32
    A addr:0x8a96040
    C addr dynamic_cast:0x8a96030
    -------------------------------
    C addr dynamic_cast:0x8a96030
    A addr ():0x8a96040
    A addr dynamic_cast:0x8a96040
    -------------------------------
    D size:32
    D addr:0x8a96060
    A addr ():0x8a96060
    A addr dynamic_cast:0x8a96060
    A1 addr dynamic_cast:0x8a96070

    下面還有篇對haoel的介紹,也一并收藏了:
    http://news.csdn.net/n/20070706/106194.html

    posted on 2011-04-24 12:52 so true 閱讀(1953) 評論(0)  編輯  收藏 所屬分類: C&C++

    主站蜘蛛池模板: 亚洲AV色无码乱码在线观看 | 国产成人亚洲午夜电影| AV无码免费永久在线观看| 亚洲高清无在码在线无弹窗| 国产精品免费网站| 亚洲熟女综合一区二区三区| 女人毛片a级大学毛片免费| 亚洲AV无码国产剧情| 国产a级特黄的片子视频免费| 国产亚洲Av综合人人澡精品| 免费在线观看理论片| 国产高潮久久免费观看| 国产亚洲一区二区在线观看| 日韩精品人妻系列无码专区免费| 亚洲毛片在线免费观看| 噜噜嘿在线视频免费观看| 瑟瑟网站免费网站入口| 亚洲另类激情综合偷自拍图| 最近免费中文字幕高清大全 | 一级毛片免费全部播放| 国产AV无码专区亚洲Av| 国产一卡二卡四卡免费| 亚洲精品久久无码| 在线亚洲精品自拍| 18禁美女黄网站色大片免费观看 | 可以免费观看的一级毛片| 国产裸体美女永久免费无遮挡| 亚洲精品国产成人99久久| 搡女人免费视频大全| 免费看又黄又爽又猛的视频软件| 国产亚洲综合一区柠檬导航| 18勿入网站免费永久| 国产亚洲一卡2卡3卡4卡新区| 亚洲综合AV在线在线播放| 91免费国产在线观看| 又长又大又粗又硬3p免费视频| 亚洲欧洲日韩国产| 亚洲性日韩精品国产一区二区| 777成影片免费观看| 一级人做人a爰免费视频| 亚洲av片不卡无码久久|