• *** C++虚函数表原理相关代码


    #include <iostream>
    
    using namespace std;
    
    class Test{
    public:
        void t(void){};
    };
    
    class Base {
    public:
        virtual void f() {cout<<"base::f"<<endl;}
        virtual void g() {cout<<"base::g"<<endl;}
        virtual void h() {cout<<"base::h"<<endl;}
    
        int n;
    };
    
    class Derive : public Base{
    public:
        void g() {cout<<"derive::g"<<endl;}
    };
    
    
    int main () {
        cout<<"size of Base: "<<sizeof(Base)<<endl;
        cout << "size of Test: " << sizeof(Test)<<endl;//Test类中没有虚函数,因此没有虚函数表
    
        typedef void(*Func)(void);
        Base b;
        Base *d = new Derive();
    
        Func f=NULL, g=NULL, h=NULL; 
        
        if (sizeof(void*) == sizeof(int))
        {
            int* pvptr = reinterpret_cast<int*>(d);
            int* vptr = reinterpret_cast<int*>(*pvptr); 
            f = (Func)vptr[0];
            g = (Func)vptr[1];
            h = (Func)vptr[2];
        }
        else if (sizeof(void*) == sizeof(long))
        {
            long* pvptr = reinterpret_cast<long*>(d);
            long* vptr = reinterpret_cast<long*>(*pvptr);  
            f = (Func)vptr[0];
            g = (Func)vptr[1];
            h = (Func)vptr[2];
        }
        else if (sizeof(void*) == sizeof(long long))
        {
            long long* pvptr = reinterpret_cast<long long*>(d);
            long long* vptr = reinterpret_cast<long long*>(*pvptr);
            f = (Func)vptr[0];
            g = (Func)vptr[1];
            h = (Func)vptr[2];
        }
    
        f();
        g();
        h();    
        
        return 0;
    }

     下面代码侧面说明,编译器在构造函数末尾处初始化vptr。所以如果在构造函数中调用virtual函数,动态绑定不会起作用,只会调用本类中的virtual函数:

    #include <iostream>
    using namespace std;
    
    class base
    {
    public:
        base()
        {
            doSth();
        }
        virtual void doSth(void)
        {
            cout << "I am Base" << endl;
        }
    };
    
    class derived: public base
    {
    public:
        virtual void doSth(void)
        {
            cout << "I am Derived" << endl;
        }
    };
    
    int main()
    {
        derived b;
        return 0;
    }

     下面代码是我自己写的读取虚函数表示例:

    #include <iostream>
    
    using namespace std;
    
    class Base{
    public:
        void func0(void)
        {
            cout << "Base::func0" <<endl;
        }
        virtual void func1(void)
        {
            cout << "Base::func1" << endl;
        }
        virtual void func2(void)
        {
            cout << "Base::func2" << endl;
        }
    
    private:
        int num1;
        int num2;
    };
    
    class Derived: public Base
    {
    public:
        void func0(void) //当Base中该函数声明为virtual,Derived中不写virtual也一样
        {
            cout << "Derived::func0" <<endl;
        }
        virtual void func1(void)
        {
            cout << "Derived::func1" << endl;
        }
        virtual void func3(void)
        {
            cout << "Derived::func3" << endl;
        }
    };
    
    typedef void (*Fun)(void);
    template <class T>
    inline Fun vTblItem(Base & obj, int i, T)
    {
        return (Fun)(*((T)(*(T)(&obj))+i));
    }
    Fun getVTblItem(Base & obj, int i)
    {
        void *p = NULL;
        if (sizeof(void*) == sizeof(int))
        {
            return vTblItem(obj, i, (int*)p);
        }
        else if (sizeof(void*) == sizeof(long))
        {
            return vTblItem(obj, i, (long*)p);
        }
        else if (sizeof(void*) == sizeof(long long))
        {
            return vTblItem(obj, i, (long long*)p);
        }
    }
    
    int main()
    {
        Derived b;
    
        getVTblItem (b,0)();
        getVTblItem (b,1)();
        getVTblItem (b,2)();
        
        Base & a = b;
        a.func0();
    
        return 0;
    }

    屏幕输出:

    Derived::func1                                                                                                                                                                     
    Base::func2                                                                                                                                                                        
    Derived::func3                                                                                                                                                                     
    Base::func0  

    如果将

    class Base{
    public:
        void func0(void)
      ... ...
    改为
    class Base{
    public:
        virtual void func0(void)
      ... ...
    则func0()也加入到了虚函数表中,并且是表中第1项。屏幕输出为:
    Derived::func0                                                                                                                                                                     
    Derived::func1                                                                                                                                                                     
    Base::func2                                                                                                                                                                        
    Derived::func0
  • 相关阅读:
    POJ1609 UVALive2815 UVA1196 ZOJ1787 Tiling Up Blocks【二维最长上升子序列+DP】
    UVALive3638 UVA12100 POJ3125 HDU1972 Printer Queue【队列+模拟】
    UVA10391 ZOJ1825 Compound Words【SET+暴力】
    NUC1157 To the Max【最大子段和+DP】
    NUC1399 Sum It Up【DFS】
    NUC1742 Subsequence【前缀和+二分搜索+尺取法】
    NUC1371 Who's in the Middle【中位数+排序】
    NUC1312 Sum【水题+数学题】
    POJ2100 Graveyard Design【尺取法】
    UVALive3399 UVA1210 POJ2739 Sum of Consecutive Prime Numbers【素数筛选+尺取法】
  • 原文地址:https://www.cnblogs.com/superrunner/p/10116300.html
Copyright © 2020-2023  润新知