C++对象模型之简单对象模型(2)

原创 2004年01月27日 21:09:00

1.3.   包含方法的对象

包含了方法的对象,其大小和内存布局应该是什么样子的呢?下面让我们来看一看。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

1.3.1. 不包含虚函数的对象

考察下面的类:

class Simple

{

public :

  Simple(char _a, int _i);

private :

  char a;

  int i;

};

它的大小应该是多少呢?数据占用了8个字节,函数应该占用多少呢?我们来做个测试。这一次让人惊异的是它的大小没发生变化,仍然是8。那么它的内存布局应该是

char a 1 Byte

补齐占位(3 Byte

int i 4 Byte

 

Simple(char _a, int _i)

Simple对象内存布局

这样的内存布局对不对呢?让我们设计一个程序验证一下。

0001   #include <iostream>

0002   #include <conio.h>

0003   using namespace std;

0004   //----------------------------------------------------------------

0005   class Simple

0006   {

0007   public :

0008     Simple(char _a, int _i);

0009   private :

0010     char a;

0011     int i;

0012   };

0013   //----------------------------------------------------------------

0014   Simple::Simple(char _a, int _i)

0015   {

0016     a = _a;

0017     i = _i;

0018   }

0019   //----------------------------------------------------------------

0020   int main(int argccharargv[])

0021   {

0022     cout << "Sizeof(Simple)" << '/t' << sizeof(Simple) << endl;

0023     Simple a('c', 9);

0024     int *ip = (int *)&a;

0025     char *cp = (char *)&a;

0026     cout << "Simple.a" << '/t' << *cp << endl;

0027     cout << "Simple.i" << '/t' << *++ip << endl;

0028     getch();

0029     return 0;

0030   }

0031   //----------------------------------------------------------------

结果符合我们的猜测。

1.3.2. 包含虚函数的对象

考察下面的类:

class Simple

{

public :

  Simple(char _a, int _i);

  virtual void vPrint(void);

  void Print(void);

private :

  char a;

  int i;

};

这一次他的大小是多少呢?按照上面的经验,函数不占据对象的存储空间,那么他的大小应该是8。对不对呢?再来检验一次。结果怎么变成“12”了呢?慢着,让我们想一想,虚函数?它意味着什么呢?虚函数意味着多态性,也就是运行期才决定调用哪个函数。那么这时如何实现的呢?答案是virtual function table,也就是通常所说的虚函数表。通过virtual function table的间接引用,我们就可以在运行期间决定调用哪一个函数。那么如何能够获得virtual function table?这就需要用到一个叫做vtbl的指针,有这个指针指向virtual function table的开始地址,那么对于虚函数的调用就变成了通过virtual function table的引用,调用函数指针。当然,这对于执行期来将是有效率的代价的。包含虚函数的对象模型如下:

void vPrint(void)

char a 1 Byte

补齐占位(3 Byte

int i 4 Byte

vtbl 4 Byte

 

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />

               数据布局                                    虚函数表

Simple(char _a, int _i)

 

void Print(void)

 

Simple对象内存布局

让我们对此作一个验证

0001   #include <iostream>

0002   #include <conio.h>

0003   using namespace std;

0004   //----------------------------------------------------------------

0005   class Simple

0006   {

0007   public :

0008     Simple(char _a, int _i);

0009     virtual void vPrint(void);

0010     void Print(void);

0011   private :

0012     char a;

0013     int i;

0014   };

0015   //----------------------------------------------------------------

0016   Simple::Simple(char _a, int _i)

0017   {

0018     a = _a;

0019     i = _i;

0020   }

0021   //----------------------------------------------------------------

0022   void Simple::Print(void)

0023   {

0024     cout << "Simple.a" << a << '/t' << "Simple.i" << i << endl;

0025   }

0026   //----------------------------------------------------------------

0027   void Simple::vPrint(void)

0028   {

0029     cout << "Simple.a" << a << '/t' << "Simple.i" << i << endl;

0030   }

0031   //----------------------------------------------------------------

0032   int main(int argccharargv[])

0033   {

0034     cout << "Sizeof(Simple)" << '/t' << sizeof(Simple) << endl;

0035     Simple a('c', 9);

0036     int *ip = (int *)&a;

0037     char *cp = (char *)&a;

0038     cout << "Simple.a" << '/t' << *cp << endl;

0039     cout << "Simple.i" << '/t' << *++ip << endl;

0040     cout << "Simple.vtbl" << '/t' << *++ip << endl;

0041     getch();

0042     return 0;

0043   }

0044   //----------------------------------------------------------------

程序的输出为:

Sizeof(Simple)  12

Simple.a        c

Simple.i        9

Simple.vtbl     4269384

非常符合我们的推测。以上是gcc的编译结果,在C++ Builder上,代码和结果略有不同

cout << "Sizeof(Simple)" << '/t' << sizeof(Simple) << endl;

Simple a('c', 9);

int *ip = (int *)&a;

char *cp = (char *)&a;

cout << "Simple.vtbl" << '/t' << *ip << endl;

cout << "Simple.a" << '/t' << *(cp+4) << endl;

cout << "Simple.i" << '/t' << *(ip+2) << endl;

程序的输出为:

Sizeof(Simple)  12

Simple.vtbl     4207548

Simple.a        c

Simple.i        9

    不同处在于vtbl在对象内存布局的开始处还是结尾处。

[读书笔记] 深入探索C++对象模型-第一章《关于对象》

最新在看深入探索C++对象模型(Inside C++ object model),看的同时针对一些之前没有留意或者理解不深的内容整理一下读书笔记,方便之后复习,也希望可以帮助到有同样疑惑的人。 下面是...
  • beyongwang
  • beyongwang
  • 2016年08月21日 21:14
  • 594

《深入理解C++对象模型》读书笔记(一)

1、           C++类对象模型的中包括非静态成员变量和虚函数表指针,其他静态成员变量和成员函数均放在对象模型之外,所有的对象示例均可以共同使用。如此可以节省访问的时间和空间效率。   ...
  • zhiren2011
  • zhiren2011
  • 2015年07月31日 10:49
  • 1072

C++对象模型之简述C++对象的内存布局

在C++中,有两种类的成员变量:static和非static,有三种成员函数:static、非static和virtual。那么,它们如何影响C++的对象在内存中的分布呢? 当存在继承的情况下,其内存...
  • ljianhui
  • ljianhui
  • 2015年05月22日 02:28
  • 9748

C++对象的内存模型

转载自:http://c.biancheng.net/cpp/biancheng/view/2995.html点击打开链接 当对象被创建时,编译器会为每个对象分配内存空间,包括成员变量和成员函数。 ...
  • chengonghao
  • chengonghao
  • 2016年04月01日 09:25
  • 1306

深度探索c++对象模型

所谓知己知彼,百战不殆。只有深入了解了c++对象的内存布局,我们才能更熟练运用c++这门语言。 运行环境vs2013一单继承和多继承的结合class C { public: C() :c(1...
  • db199410
  • db199410
  • 2016年06月16日 17:40
  • 375

C++对象模型浅析

VTable 虚表 虚表的内存分布 一个简单的包含虚函数的类的声明 class A { public: virtual void v_a(){} virtual ~A...
  • whn_arthur
  • whn_arthur
  • 2016年02月23日 17:29
  • 369

C++面向对象模型初探

C++中的class从面向对象理论出发,将变量(属性)和函数(方法)集中定义在一起,用于描述现实世界中的类。从计算机的角度,程序依然由数据段和代码段构成。 C++编译器如何完成面向对象理论到计算机程序...
  • lishuhuakai
  • lishuhuakai
  • 2015年05月23日 00:32
  • 868

c++对象内存模型【内存布局】

#类中的元素 0. 成员变量   1. 成员函数   2. 静态成员变量   3. 静态成员函数   4. 虚函数   5. 纯虚函数 #影响对象大小的因素 0. 成员变量   ...
  • IT_YUAN
  • IT_YUAN
  • 2014年04月28日 16:30
  • 11863

详细介绍C++中的类对象内存模型

内存模型描述的是程序中各变量(实例域、静态域和数组元素)之间的关系,以及在实际计算机系统中将变量存储到内存和从内存取出变量这样的低层细节.不同平台间的处理器架构将直接影响内存模型的结构. 首先介绍一...
  • ywcpig
  • ywcpig
  • 2016年09月12日 23:14
  • 2088

领域模型和领域对象的概念

面向对象架构模式之:领域模型(Domain Model) 领域模型是对领域内的概念类或现实世界中对象的可视化表示。又称概念模型、领域对象模型、分析对象模型。它专注于分析问题领域本身,发掘重要的业务领...
  • wlanye
  • wlanye
  • 2016年08月18日 13:52
  • 4288
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++对象模型之简单对象模型(2)
举报原因:
原因补充:

(最多只允许输入30个字)