vc的sizeof

来源:互联网 发布:涂涂乐源码 编辑:程序博客网 时间:2024/05/16 11:08
对于这个问题:首先说明一下不带虚函数时候的情况,其分配规则为:
VC对一些变量的起始地址做了“对齐”处理。在默认情况下,VC规定1.各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。下面列出常用类型的对齐方式(vc6.0,32位系统)。
类型             对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
Char             偏移量必须为sizeof(char)即1的倍数
Short           偏移量必须为sizeof(short)即2的倍数
int       偏移量必须为sizeof(int)即4的倍数
float   偏移量必须为sizeof(float)即4的倍数
double      偏移量必须为sizeof(double)即8的倍数
各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时2.VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
===========================
上面红色的部分是两条主要的规则。而绿色的部分是解决这个问题的关键。
代码实例1
C/C++ code
#include <iostream> using namespace std; class A { double a; char b; int c;}; void main() { cout < <sizeof(A) < <endl; }

对于你的问题,我们把最后的虚函数改为int   ;根据规则1,a占8个字节,b占1个字节,而后c要根据规则1对齐,所以b后面会有3个字节被填充掉,c从b后的第4个字节开始。它占4个,最后结果是:8+(1+3)+4=16。同时符合了规则2。所以为16。
用图表示为:
--
a     8个字节
---
b   一个字节
----
三个填充字节
-----
c     四个字节
---
那么现在请注意上面文字中的绿色部分。我们改变一下顺序。
代码实例2
C/C++ code
#include <iostream> using namespace std; class A { int c;double a; char b; }; void main() { cout < <sizeof(A) < <endl; }

那么开始的c占4个字节,根据规则1,a在分配之前,c和a之间的距离应该为8,即c后面有4个空间需要被填充。对于b,其占一个字节。所以最后是(4+4)+8+1=17;根据规则2,整个类要是8的倍数,所以b后面会再填充7个,即17+7=24。
图示:
----
c     四个字节
----
4个填充
----
a     八个字节
---
b     一个字节
----
七个填充字节
------
接下来是本帖的解答:
既然虚函数指针也是4个字节,那么结果为什么不是16呢?而是24呢。?
因为在分配空间的时候,其顺序是先分配虚函数表指针,然后才是变量的。所以虚函数在类中的位置对类的大小无影响,其始终是在最前面的。
用图实例:
----
vptable   4个字节
-------
4个填充
-----
a   八个
-----
b   一个
-----
7个填充。。

==========
总结:本帖的关键是虚函数表指针不是按照它在类中出现的顺序分配的,而是总是首先被分配的。你可以把他放到类中的其他位置,做实验,始终是24。。。。 
 
原创粉丝点击