Bootstrap

c++中虚基类表和虚函数表的布局

本文涉及到C++中对象的内存布局知识,若无该方面基础建议先阅读haoel(陈皓)专栏的C++对象内存布局的博客:
http://blog.csdn.net/haoel/article/details/3081328

在拜读上述博客之后,我深受启发,且对C++关于虚函数表的问题有了新的认识和疑惑。比如,在上述博客的最后作者抛出了一个问题:在VS环境下,对象虚函数表指针的下一个字中,存储的不是对象的成员变量,而是一个取值后为-4的地址。这个地址代表什么呢?虚函数表上是如何放置基类和派生类的虚函数呢?

注意:对于在对象中存取虚基类的问题,虚基类表仅是Microsoft编译器的解决办法。在其他编译器中,一般采用在虚函数表中放置虚基类的偏移量的方式。

通过实验,我得到了这样的结论:
1. 一个对象实例只有一个虚函数表,只有一个虚基类表。
2. 对象的每个基类都有一个属于自己的虚函数表指针(vfptr)指向虚函数表(vftbl)的某一项,都有一个属于自己的虚基类表指针(vbptr)指向虚基类表(vbtbl)的某一项。
3. 虚函数表中按照对象继承的顺序排列对象的虚函数地址,虚基类表中按照对象继承的顺序排列对象的直接虚继承类到虚基类的偏移。
4. 当基类无虚函数,且派生类有独立虚函数时,派生类对象起始位置为自己的虚函数表指针。否则派生类的虚函数会归到第一个带虚函数表指针的基类的虚函数表指向范围,这样就节省了一个vfptr的空间。

沿用上述博客的代码:

class B
{
public:
    int ib;
    char cb;
public:
    B() :ib(0), cb('B') {}

    virtual void f() { cout << "B::f()" << endl; }
    virtual void Bf() { cout << 
;