1
virtual void dev_class::v_func1()
{
    base_class::v_func1();
    cout << "This is dev_class's v_func1()" << endl;
}

dev_classのv-tableでは、すでに。base_class::v_func1()によってオーバーライドされています dev_class::v_func1()。では、なぜdev_class::v_func1()電話できるのbase_class::v_func1()でしょうか。関数アドレスはどこにbase_class::v_func1()保存されますか?

4

3 に答える 3

3

呼び出しで修飾関数名を使用すると、「v-tables」を使用せずに、指定された関数が直接呼び出されます。これは、派生クラスメンバー関数からの基本クラスメンバー関数の呼び出しに適用されます(例のように)。これは、他のすべてのコンテキストでのメンバー関数呼び出しにも当てはまります。

例えば

base_class *p = new dev_class;
p->v_func1(); // virtual call - calls `dev_class::v_func1`
p->base_class::v_func1(); // non-virtual call - calls `base_class::v_func1`

修飾された関数名は、仮想ディスパッチメカニズムを抑制およびオーバーライドし、仮想メンバー関数呼び出しを通常のメンバー関数呼び出しに効果的に変換します。

于 2012-07-11T07:06:49.167 に答える
2

base_class::v_func1()非仮想関数と同様に、vテーブルを使用せずに呼び出されます。

于 2012-07-11T06:44:13.040 に答える
1

コンパイラは、すべてのクラスのすべての仮想テーブルのアドレスを知っているだけです。これは、「コンパイラがコンストラクタでVMTを設定する方法」を尋ねるのと同じですか?VMTに格納されている関数のアドレスは単なる関数であり、コンパイラーにはほとんど同じ方法で認識されています。

于 2012-07-11T06:43:54.803 に答える