Inside The C++ Object Model 读书笔记(一)

  自己对于C++的理解一向都不太深入,看到貌似许多牛人都读过这本Inside The C++ Object Model,似乎深入了解C++必须读这本书,于是决定啃一下。到手当天看了下目录就知道这绝对是本好书。很多C++的书不知道是出于什么目的,要么不想讲清楚,要么就是讲不清楚,总之根本就没有将C++的一些机制写出来,即使写出来也有很多具有二义性,让人完全不知所措。

  好了,闲话少说。之所以C++有许多很难理解的东西,原因之一就是C++背着我们做了太多的事情。这是我拿到这本书之后的第一反应。

  第一个解决的问题就是C++对象模型。C++对象模型究竟是什么样子,反正我在看这本书之前完全没有概念,可能和我没学过编译原理有关,所以对于如下一些问题,就完全不知所措:

 1 class A{};
 2 
 3 class B{
 4 public:
 5   int a;
 6   static int b;    
 7 };
 8 
 9 class C{
10 public:
11   char id;
12   char num;
13   int data;
14   C();
15   ~C();
16   void setid();
17 private:
18   void funtion();                
19 };
20 
21 class D:public C{
22 virtual void function()=0;
23 };
24 
25 sizeof(A)=?
26 sizeof(B)=?
27 sizeof(C)=?
28 sizeof(D)=?

  一个空类,或者空类的对象,它的大小是多少,为什么?每一个类的大小是多少,为什么?这些问题在读完第一章并联系第三章以后便豁然开朗。

  首先对于一个空类,实际上它并不是空的,它有一个隐藏的1byte的char,这样设计的原因是,能让这样一个类的不同对象能够配置在一个独一无二的地址上,能够区分开来。所以sizeof(A)=1。这就是C++编译器背着我们做的动作之一,也就是所谓implicit code。程序员写的代码基本上都应该叫做explicit code, 而编译器添加进去的则称之为implicit code。

  对于后面的问题,需要描述C++对象模型,以一个Point类为例:class Point{

public:
   int _x;
   int _y;

  static char _z;
  Point();
virtual void function1(); virtual void function2(); };

  类中有两个int类型的成员变量,一个声明为static的char型成员变量,一个构造函数,两个虚函数,现在我们来看一下其真正的对象模型结构:

  

  也就是说,真正的对象(非空)中,并不是声明了什么就有什么,而是只包含声明的非静态成员变量,和一个指向一个Virtual table的指针。

  这样我们对对象的结构和大小就一目了然了,若类中没有声明或者继承虚函数时,那么就是对象的大小就是非静态成员变量的大小之和(这里先不考虑字节对齐的问题),如果有虚函数则对象中保存了一个指向虚函数表的指针,这个虚函数表是为了定位虚函数而设定的,而一个指针在32位的机器上占4个字节,所以这样pt对象的大小就是12个字节。而对于上面的示例,B类中有两个成员变量,但是静态成员变量不存储在对象中,所以sizeof(B)=4;C类中有3个非静态成员变量,而32位的机器上默认是4字节对齐,所以两个char和一个int共占用8个字节,sizeof(C)=2+2+4=8;因为D继承了C,子类也拥有父类的成员,而且class D还有虚函数,需要有一个指向虚函数表的指针,因此sizeof(D) = 12。

  所以说C++背着我们做了太多的事情~!不了解编译器或者说设计的思想,就永远被蒙在鼓里。

  

原文地址:https://www.cnblogs.com/XiaoHDeBlog/p/3095936.html