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