对象结构的发展和演化
类对象所占用的空间
- 类的成员函数不占用类的内存空间
- 一个类对象至少占用1个字节的内存空间
- 成员变量占用对象的内存空间
总结:成员变量是包含在每个对象中的,是占用对象字节的。而成员函数虽然也写在类的定义中,但成员函数不占对象字节数的(不占用内存空间)。
c++对象模型逐步建立起来
- 非静态的成员变量(普通成员变量)跟踪类对象走(存在对象内部),也就是每个类对象都有自己的成员变量
- 静态成员变量跟对象没有什么关系,所以肯定不会保存在对象内部,是保存在对象外面的
- 成员函数:不管静态的还是非静态的,全部保存在类对象之外。所以不管有几个成员函数,不管是否是静态的成员函数,对象的sizeof的大小都是不增加的
- 虚函数:不管几个虚函数,sizeof()都是多了4个字节
- 类里只要有一个虚函数(或者说至少有一个虚函数),这个类会产生一个指向虚函数的指针
- 有两个虚函数,那么这个类就会产生两个指向虚函数的指针
- 类本身指向虚函数的指针(一个或者一堆)要有地方存放,存放在一个表格里,这个表格我们称为”虚函数表(virtual table[vtbl])“,这个虚函数表一般保存在可执行文件中的,在程序执行的时候载入到内存中来
- 虚函数表是基于类的,跟着类走的
- 说说类对象,这4个字节的增加,其实是因为虚函数的存在,因为有了虚函数的存在,导致系统往类对象中添加了一个指针,这个指针正好指向这个虚函数表(vptr)。这个vptr的值有系统在适当的时机(比如构造函数中通过增加额外的代码)
总结:对于类中
- 静态数据成员不计算在sizeof内
- 普通成员函数和静态成员函数不计算在类对象的sizeof()内
- 虚函数不计算在类对象的sizeof()内,但是虚函数会让类对象的sizeof()增加4个字节以容纳虚函数表指针
- 虚函数表(vtbl)是基于类的(跟着类走,跟对象没关系,不是基于对象的)
- 如果有多个数据成员,那么为了提高访问速度,某些编译器可能会将数据成员之间的内存占用比例进行调整。(内存字节对齐)
- 不管什么类型的指针(char *p, int *q)该指针占用内存的大小是固定的
