私は仮想関数に関していくつかの疑問を持っています。それよりも、ランタイム ポリモーフィズムと言えます。私によると、私はそれが以下のように機能する方法を想定しました、
仮想テーブル (V-Table) は、少なくとも 1 つの仮想メンバー関数を持つすべてのクラスに対して作成されます。これは静的テーブルだと思うので、すべてのオブジェクトではなく、すべてのクラスに対して作成されます。ここで間違っている場合は、これを修正してください。
この V-Table には、仮想機能のアドレスがあります。クラスに 4 つの仮想関数がある場合、このテーブルには、対応する 4 つの関数を指す 4 つのエントリがあります。
コンパイラは、クラスの隠しメンバーとして仮想ポインター (V-Ptr) を追加します。この仮想ポインタは、仮想テーブルの開始アドレスを指します。
このようなプログラムがあるとします。
class Base
{
virtual void F1();
virtual void F2();
virtual void F3();
virtual void F4();
}
class Der1 : public Base //Overrides only first 2 functions of Base class
{
void F1(); //Overrides Base::F1()
void F2(); //Overrides Base::F2()
}
class Der2 : public Base //Overrides remaining functions of Base class
{
void F3(); //Overrides Base::F3()
void F4(); //Overrides Base::F4()
}
int main()
{
Base* p1 = new Der1; //Believe Vtable will populated in compile time itself
Base* p2 = new Der2;
p1->F1(); //how does it call Der1::F1()
p2->F3(); //how does it call Base::F3();
}
V-Table がコンパイル時に読み込まれる場合、なぜそれをランタイム ポリモーフィズムと呼ぶのでしょうか? 上記の例を使用して、vtables と vptr の数と、それがどのように機能するかを説明してください。私によると、Base、Der1、および Der2 クラス用に 3 つの Vtables があります。Der1 Vtable では、独自の F1() および F2() のアドレスを持ちますが、F3() および F4() のアドレスは Base クラスを指します。また、3 つの Vptr が Base、Der1、および Der2 クラスの隠しメンバーとして追加されます。コンパイル時にすべてが決定されている場合、実行時に正確に何が起こるのでしょうか?. 概念が間違っている場合は修正してください。