关于虚函数表示例二小节存在的小问题。
从视频中可以看出作者用的是 32 位的操作系统,
因此在该小节中说将的东西在 32 位操作系统上都是对得上,
而在 64 位操作系统上就会有如下问题:
内存对齐导致输出不一样,比如在该小节中为父类加了符合规定的虚函数(就是符合虚函数规则的函数,如虚析构函数、虚成员函数等等),父类输出的结果为 8,这里毋庸置疑,而子类的结果却为:16。这就会让一些基础比较弱的同学一头雾水,WTH?为什么是 16 ,而不是 4 + 8 = 12 呢?这里面有几个知识点:
1. 内存对齐,因为指针的大小为 8 个字节,而 int 类型的大小为 4 个字节,则有 8 + 4 = 12,12 / 8 不等于一个整数,不符合内存对齐原理,因此为了符合内存对齐的原理额外加了 4 个字节, (12 + 4) / 8 = 2,因此这就是为什么输出 16 的原因
2. 从上面第一个知识点可以猜测出,系统是把虚函数表指针放在了对象的第一个成员属性上,为什么了。因为如果是把 m_iR 放在第一个位置上的话,则 (4 + 8) / 4 = 3 ,符合内存对齐原理,那么输出的应该为 12。
3. 由上面两个知识点可以知道另一个知识点,那就是我们在 q++ 之后输出的值不是我们期望的 100,那是因为内存对齐会填充不足的字节,具体如下所示:
void *p; (虚函数表指针 8 个字节)
int m_iR; (int 类型 4 个字节)
char pad[4]; (填充的 4 个字节)
那么在我们执行 q++ 时,指针的位置只是向后偏移了 4 个字节(int 类型占 4 个字节),而指针的大小占 8 个字节。
因此我们还需要再执行一次 q++ ,这时 q 指针所指向的地址才是我们期望 m_iR 的地址,输出才是我们期望的 100。