vptr と vtable について説明している記事を見つけました。仮想関数が格納されているクラスの場合、オブジェクトの最初のポインターはvtableへのvptrであり、vtableの配列エントリは、クラスで発生するのと同じ順序で関数へのポインターであることを知っています(テストで確認しました)プログラム)。しかし、適切な関数を呼び出すためにコンパイラがどの構文を配置する必要があるかを理解しようとしています。
例:
class Base
{
virtual void func1()
{
cout << "Called me" << endl;
}
};
int main()
{
Base obj;
Base *ptr;
ptr=&obj;
// void* is not needed. func1 can be accessed directly with obj or ptr using vptr/vtable
void* ptrVoid=ptr;
// I can call the first virtual function in the following way:
void (*firstfunc)()=(void (*)(void))(*(int*)*(int*)ptrVoid);
firstfunc();
}
質問:
1.しかし、私が本当に理解しようとしているのは、コンパイラが呼び出しを ? に置き換える方法ptr->func1()
ですvptr
。通話をシミュレートする場合、どうすればよいですか? ->
演算子をオーバーロードする必要があります。しかし、実際の名前がわからないので、それでも役に立ちませんfunc1
。コンパイラが vptr を介して vtable にアクセスするとしても、のエントリがfunc1
最初の配列であり、のエントリが配列func2
の 2 番目の要素であることをどうやって知るのでしょうか? 関数の名前から配列の要素へのマッピングが必要です。
2.どうすればシミュレートできますか? コンパイラが関数を呼び出すために使用する実際の構文を提供できますfunc1
か (どのように を置き換えptr->func1()
ますか)?