C++虚関数テーブルノート

1747 ワード

虚関数や虚表についての紹介はネット上では牛の毛のように多く、疲れていないので、次のいくつかのポイントを説明します.
ダミー関数テーブルはコンパイル中に生成され、コードセグメントに格納され、ダミー関数は宣言された順序で格納されます.
親の虚関数は必ず子の虚関数テーブルに存在する
C++のオブジェクト虚関数の呼び出し、例えばDerive*f=new Base;f->func(int a, ...) 実際にはxxxxxfunctionnamexxx(Base*,int,...)にコンパイルされます.このような
コンパイルフェーズで関数が虚でない場合、パラメータはスタックを圧縮し、関数エントリにジャンプして実行します.虚関数の場合は、まず表を調べて、具体的な関数の入り口を見つけて、スタックを押してジャンプします.
詳しいブログはhttp://blog.csdn.net/linyt/article/details/6336762
#include <iostream>
using namespace std;

void cal() {}

class A{
public:
    virtual void f(int s){ cout<<"Base"<<endl; }
};

class B: public A{
public:
    virtual void f(int s){
        cout<<s<<endl;
    }
};

class C: public A{
public:
    virtual void f(int s){
        cout<<-s<<endl;
    }
};

int bss_seg;
int data_seg = 1;
int data_seg_1 = 2;
int big_data_seg[(int)1e7];

int main() {
    B b;
    A * a = &b;
    a->f(1);
    void (*f)(A*, int) = NULL;
    void*** vt = (void***) a;
    f = (void (*)(A*,int) )( (*vt)[0] );
    f(a, 111);

    int stack_seg;
    int *mmp_seg = new int[200*1024];
    int *heap_seg = new int;

    cout<<&stack_seg<<endl;
    cout<<mmp_seg<<endl;
    cout<<heap_seg<<endl;
    cout<<&bss_seg<<endl;
    cout<<endl;

    cout<<&data_seg<<endl;
    cout<<&data_seg_1<<endl;
    cout<< ( (big_data_seg) ) <<endl;


    cout<<(void*)cal<<endl;
    cout<<(void*)f<<endl;

    C c;
    a = &c;
    a->f(1);
    vt = (void***) a;
    f = (void (*)(A*,int) )( (*vt)[0] );
    f(a, 111);
    cout<<(void*)f<<endl;

    return 0;
}