zoukankan      html  css  js  c++  java
  • C++多重继承虚表的内存分布

    接前面虚表的内存分布,今天重点看多重继承的虚表内存分布,简单的说,继承几个类便有几个虚表,如下代码

    class Drive : public Base1, public Base2, public Base3 {
    public:
        virtual void fd() { cout << "Drive::fd" << endl; }
        virtual void gd() { cout << "Drive::gd" << endl; }
    };

    则虚表有3个,如下图所示:

    添加更多的测试代码:

    // trytest.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    
    #include <WTypes.h>
    #include < iostream >
    
    using namespace std;
    
    class Base1 {
        virtual void f() { cout << "Base1::f" << endl; }
        virtual void g() { cout << "Base1::g" << endl; }
    };
    
    class Base2 {
        virtual void f() { cout << "Base2::f" << endl; }
        virtual void g() { cout << "Base2::g" << endl; }
    };
    
    class Base3 {
        virtual void f() { cout << "Base3::f" << endl; }
        virtual void g() { cout << "Base3::g" << endl; }
    };
    
    class Drive : public Base1, public Base2, public Base3 {
    public:
        virtual void fd() { cout << "Drive::fd" << endl; }
        virtual void gd() { cout << "Drive::gd" << endl; }
    };
    
    typedef void(*Fun)(void);
    
    int main() {
        Drive objDrive;
        cout << "Size is = " << sizeof(objDrive) << endl; 
    
        Fun pFun = NULL;
    
        cout<<"sizeof(int)="<<sizeof(int)<<endl;
        cout<<"sizeof(int*)="<<sizeof(int*)<<endl;
    
        // 调用Base1的第一个虚函数
        pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 0);
        pFun();
        // 调用Base1的第二个虚函数
        pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 1);
        pFun();
        cout << "Address of virtual pointer 1 " << (int*)(&objDrive + 0) << endl;
        cout << "Value at virtual pointer i.e. Address of virtual table " 
            << (int*)*(int*)((int*)&objDrive + 0) << endl;
        cout << "Information about VTable 1" << endl; 
        cout << "Value at 1st entry of VTable " 
            << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 0) << endl; 
        cout << "Value at 2nd entry of VTable " 
            << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 1) << endl; 
    
    
    
        // 调用Base2的第一个虚函数
        pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 1) + 0);
        pFun();
        // 调用Base2的第二个虚函数
        pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 1) + 1);
        pFun();
        cout << "Address of virtual pointer 2 " << (int*)((int*)&objDrive + 1) << endl;
        cout << "Value at virtual pointer i.e. Address of virtual table " 
            << (int*)*(int*)((int*)&objDrive + 1) << endl;
        cout << "Information about VTable 2" << endl; 
        cout << "Value at 1st entry of VTable " 
            << (int*)*((int*)*(int*)((int*)&objDrive + 1) + 0) << endl; 
        cout << "Value at 2nd entry of VTable " 
            << (int*)*((int*)*(int*)((int*)&objDrive + 1) + 1) << endl; 
    
        // 调用Base3的第一个虚函数
        pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 2) + 0);
        pFun();
        // 调用Base3的第二个虚函数
        pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 2) + 1);
        pFun();
        cout << "Address of virtual pointer 3 " << (int*)((int*)&objDrive + 2) << endl;
        cout << "Value at virtual pointer i.e. Address of virtual table " 
            << (int*)*(int*)((int*)&objDrive + 2) << endl;
        cout << "Information about VTable 3" << endl; 
        cout << "Value at 1st entry of VTable " 
            << (int*)*((int*)*(int*)((int*)&objDrive + 2) + 0) << endl; 
        cout << "Value at 2nd entry of VTable " 
            << (int*)*((int*)*(int*)((int*)&objDrive + 2) + 1) << endl; 
    
        // 调用派生类的第一个虚函数
        pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 2);
        pFun();
        // 调用派生类的第二个虚函数
        pFun = (Fun)*((int*)*(int*)((int*)&objDrive + 0) + 3);
        pFun();
        cout << "Value at 3rd entry of VTable " 
            << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 2) << endl; 
        cout << "Value at 4th entry of VTable " 
            << (int*)*((int*)*(int*)((int*)&objDrive + 0) + 3) << endl; 
    
     
        //明确多重继承中虚函数的内存位置
        cout <<"Address at 1st entry of VTable "
            << (int*)*((int*)&objDrive + 0) + 0 << endl; 
    
        cout <<"Address at 2nd entry of VTable "
            << (int*)*((int*)&objDrive + 0) + 1 << endl; 
    
        cout <<"Address at 3rd entry of VTable "
            << (int*)*((int*)&objDrive + 0) + 2 << endl; 
    
        cout <<"Address at 4th entry of VTable "
            << (int*)*((int*)&objDrive + 0) + 3 << endl; 
    
        pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 0);
        pFun();
    
        pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 1);
        pFun();
    
        pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 2);
        pFun();
    
        pFun = (Fun)*((int*)*((int*)&objDrive + 0) + 3);
        pFun();
    
    
        return 0;
    }

    内存分布如下所示:

  • 相关阅读:
    VueBlog
    java 代理模式
    集合框架
    面试题
    java 多线程
    网络编程
    HTTP
    MAVEN
    Redis高级
    深入浅出--梯度下降法及其实现
  • 原文地址:https://www.cnblogs.com/luhouxiang/p/3215343.html
Copyright © 2011-2022 走看看