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)。
          我先區別兩個概念“類的內存布局(由此可以計算出類的大小)”和“類本身的內存布局(由此可以計算出類本身的大小)”:
          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 閱讀(1954) 評論(0)  編輯  收藏 所屬分類: C&C++

          主站蜘蛛池模板: 伊川县| 贡嘎县| 读书| 宿迁市| 商洛市| 长丰县| 册亨县| 明星| 武安市| 抚宁县| 乌审旗| 岢岚县| 秦皇岛市| 沙河市| 武功县| 丹巴县| 永新县| 山东省| 曲周县| 当雄县| 大新县| 沈阳市| 潢川县| 德钦县| 台东县| 罗田县| 成都市| 昭苏县| 安国市| 阳信县| 平武县| 望谟县| 从江县| 海晏县| 岗巴县| 盐源县| 临颍县| 连江县| 阜南县| 栖霞市| 东丰县|