首页 > 编程语言 > 详细

C++ 对象的内存布局

时间:2015-11-18 12:08:05      阅读:466      评论:0      收藏:0      [点我收藏+]

 

这里的例子全部来自陈皓的  C++ 对象的内存布局(上),经过修改的。

编译器:g++ (Ubuntu 4.9.2-10ubuntu13) 4.9.2

环境:ubuntu 15.04  64位系统(地址占8字节)

 

例子1:

  单一的一般继承,所有函数均是virtual,每个类中均有1个long long变量:

技术分享

 1 class Parent {
 2 public:
 3     LL iparent;
 4     Parent ():iparent (10) {}
 5     virtual void f() { cout << " 1 " << endl; }
 6     virtual void g() { cout << " 2 " << endl; }
 7     virtual void h() { cout << " 3 " << endl; }
 8  
 9 };
10  
11 class Child : public Parent {
12 public:
13     LL ichild;
14     Child():ichild(100) {}
15     virtual void f() { cout << " 11 " << endl; }
16     virtual void g_child() { cout << " 4 " << endl; }
17     virtual void h_child() { cout << " 5 " << endl; }
18 };
19  
20 class GrandChild : public Child{
21 public:
22     LL igrandchild;
23     GrandChild():igrandchild(1000) {}
24     virtual void f() { cout << " 111 " << endl; }
25     virtual void g_child() { cout << " 44 " << endl; }
26     virtual void h_grandchild() { cout << " 6 " << endl; }
27 };
28 int main(void)
29 {
30     typedef void(*Fun)(void);
31     GrandChild gc;
32  
33     LL** pVtab = (LL**)&gc;
34     Fun pFun=NULL;
35 
36     cout << "[0] GrandChild::_vptr->" << endl;
37     for (int i=0; i<6; i++){
38         pFun = (Fun)pVtab[0][i];
39         cout << "    ["<<i<<"] ";
40         pFun();
41     }
42     LL *p=(LL*)&gc;
43     cout << "[1] Parent.iparent = " <<*(p+1)<< endl;
44     cout << "[2] Child.ichild = " << *(p+2)<< endl;
45     cout << "[3] GrandChild.igrandchild = " << *(p+3)<< endl;
46     
47     cout<<"对象gc的大小:"<<sizeof(gc)<<endl;    
48  
49     return 0;
50 }

输出:

技术分享

  解释:继承关系为 Parent<--Child<--GrandChild,其中Child是中间类,覆盖了Parent中一个函数f。GrandChild是最底派生类,覆盖了Parent和Child的函数f,再覆盖Child中的函数g_child。

  总结:GrandChild的对象gc一共占4*8=32个字节。其中首项是虚函数表指针,剩下的3项是3个类中的成员变量,按继承的声明顺序排列。虚函数表中有6个函数,其中来自GrandChild的有3个,Child的1个,Parent的2个。GrandChild的3个必定不会少,而且前两个函数f和g_child就覆盖掉所有基类中同名的函数。Parent中剩下2个没有被覆盖的,而f不幸被覆盖。Child中只剩下1个了,前两个都被覆盖了。

  其实可以先看两层的Parent<--Child,而GrandChild先不看。那么派生类覆盖掉基类1个函数,剩下的就是2+3=5个函数。来了新的基类GrandChild后,也新来3个函数,但是其中2个已经存在,先覆盖,剩下一个直接加进去,即5+1=6个函数。

  验证了如下这副图:

  技术分享

 

 

例子2:

 

 

C++ 对象的内存布局

原文:http://www.cnblogs.com/xcw0754/p/4973978.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!