C++对象内存布局--虚基类表的使用

一、测试VS编译器,虚基类表在函数调用时是怎么使用的

1、测试代码:

//虚基类表指针的使用.cpp
//2010.8.19
//使用VC++6.0/VS2005/VS2008编译器编译,OllyDbg反汇编工具调试查看虚基类表的使用。
#include <iostream>
using namespace std;
////////////////////////////////////////////////////////////////
class Base
{
    public:
        Base(int a = 10):a(a)
        {
        }
        virtual void show()
        {
            cout << "Base::show()" << endl;
        }
        virtual void testA()
        {
            cout << "Base::testA()" << endl;
        }
    private:
        int a;
};
////////////////////////////////////////////////////////////////
class BaseA : virtual public Base
{
    public:
        BaseA(int b = 20):b(b)
        {
        }
        virtual void showA()
        {
            cout << "BaseA::showA()" << endl;
        }
        void testA()
        {
            cout << "BaseA::testA()" << endl;
        }
    private:
        int b;
};
////////////////////////////////////////////////////////////////
class BaseB : virtual public Base
{
    public:
        BaseB(int c = 30):c(c)
        {
        }
        virtual void showB()
        {
            cout << "BaseB::showB()" << endl;
        }
    private:
        int c;
};
////////////////////////////////////////////////////////////////
class Derived : public BaseA, public BaseB
{
    public:
        Derived(int d = 40):d(d)
        {
        }
        virtual void show()
        {
            cout << "Derived::show()" << endl;
        }
        virtual void test()
        {
            cout << "Derived::test()" << endl;
        }
    private:
        int d;
};
////////////////////////////////////////////////////////////////
int main()
{
    Derived obj;
	cout << "start" << endl;//为方便反汇编调试设置的标记
	Base *pb = &obj;
	pb->show();
	cout << "start" << endl;//为方便反汇编调试设置的标记、
	system("pause");
    return 0;
}

2、使用OllyDbg反汇编调试的相关结果:

 

图 1 VC++6.0编译器,OD调试结果

 

图 2 VS2005/2008编译器,OD调试结果

3、结果表明,在调用虚基类函数的时候,有使用到虚基类表指针。

二、测试GCC编译器,虚基类表在函数调用时是怎么使用的

1、测试代码跟上边的一样。

2、使用OllyDbg反汇编调试的相关结果:

 

图 3 GCC编译器,OD调试结果

3、结果表明,在调用虚基类函数的时候,没用到虚基类表指针,直接:ADD EAX, 14,获取虚基类实例地址。可能是测试的代码比较简单,编译器做了优化。

posted on 2010-08-20 01:40  烛秋  阅读(3940)  评论(0编辑  收藏  举报