在一些面试过程的时候,有时候会问到有关内存对齐相关的问题,比如结构体的大小,这些问题的回答就必须要考虑内存对齐的问题了。记得有次电话面试,面试官问我一个空类的大小是多少,当时自己回答是0字节,但后来验证了一下才知道原来是1字节。为什么空类的大小是1字节呢,而不是4字节或其它呢?
从下面的代码结合来分析一下:
#include <iostream>
#include <cstdio>
using namespace std;
class Empty {
};
int main()
{
printf("%d\n", sizeof(Empty));
Empty e1;
Empty e2(e1);
e2 = e1;
return 0;
}
输出的结果是1字节。
为什么会是一个字节呢?此时空类中包含了哪些东西呢?在看《Effective C++》时,条款5说到了编译器会自动的为空类声明一个copy构造函数、一个copy assignment操作符和一个析构函数,编译器产生的析构函数是non-virtual的。如果没有声明一个default构造函数,编译器也会自动为其生成一个,所有的这些函数都是public和inline的。
从正面中我们可能比较难以理解。在VC6.0反汇编的代码我们来看看。
52: printf("%d\n", sizeof(Empty));
00401048 6A 01 push 1
0040104A 68 1C E0 42 00 push offset string "%d\n" (0042e01c)
0040104F E8 0C 71 00 00 call printf (00408160)
00401054 83 C4 08 add esp,8
push 1就是表示空类的大小是1个字节了。这里也可以知道printf的格式化字符串是放在常量数据区的,直接以地址来标识。知道函数调用约定的人就明白上面的代码了。可以参考博客的一个文章。
53: Empty e1;
54: Empty e2(e1);
00401057 8A 45 FC mov al,byte ptr [ebp-4]
0040105A 88 45 F8 mov byte ptr [ebp-8],al
55: e2 = e1;
0040105D 8A 4D FC mov cl,byte ptr [ebp-4]
00401060 88 4D F8 mov byte ptr [ebp-8],cl
从类的对象进行的操作我们也知道编译器在背后为我们做了一些事情。
从汇编代码我们就可以看出,操作数都是byte的。也就是说空类只是给了一个计算机能够表示的最小单位,这里一个字节是在Win32平台的,其它的平台暂时不知道。留个问题:一个类的大小究竟包含哪些内容?这些都是一些基础的知识,所以在笔试或者面试的时候会经常考的。