Q:字节对齐
对于一些平台,特定的数据类型只能从特定的地址进行读取,随意防止将导致错误。而更一般的情况是,如果不按照规定存放数据,将会造成读写效率上的损耗。比如32位的Intel处理器通过总线访问(包括读和写)内存数据。每个总线周期从偶地址开始访问32位内存数据,内存数据以字节为单位存放。如果一个32位的数据没有存放在4字节整除的内存地址处,那么处理器就需要2个总线周期对其进行访问,显然访问效率下降很多。
对于结构体的对齐问题和编译器有关,一般满足一下规则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节{trailing padding}。
在VC/C++中,栈的对齐方式不受结构体成员对齐选项的影响。总是保持对齐且对齐在4字节边界上。
Q:虚函数的实现原理
虚函数的是c++的多态的一种。对于声明虚函数的类,会创建一个虚函数表,并为每个对象添加一个隐藏的成员指针来指向该类的虚函数表。在继承过程从,子类会继承父类的虚函数表,当子类重写虚函数时,会将对虚函数表中对应的函数进行修改。
当调用虚函数时,对象会先根据指针去寻找虚函数表,然后再找到对应的函数地址。因此,相比于静态联编的非虚函数,虚函数在效率上会有一定的损失。
对于一个空的类来说,其对象大小为一个字节。而对于一个空的具有虚函数的类来说,因为隐藏指针的存在,其大小为一个指针所占大小。