22

「仮想関数が宣言されたクラスには仮想テーブルが存在する」と書いている人をたくさん読んでいます。

私の質問は、vtableは仮想関数を持つクラスにのみ存在するのか、それともそのクラスから派生したクラスにも存在するのかということです。

例えば

class Base{
    public:
        virtual void print(){cout<<"Base Print\n";}
};
class Derived:public Base{
    public:
        void print(){cout<<"Derived print\n";}
};

//From main.cpp 
Base* b = new Derived;
b->print();

質問:派生したクラスのvtableがなかった場合、出力は「派生した印刷」ではなかったでしょう。したがって、IMOには、仮想関数が宣言されているクラスと、そのクラスから継承するクラスのvtableが存在します。これは正しいです ?

4

4 に答える 4

19

仮想関数固有の機能のみが考慮される限り、vtable実装への従来のアプローチでは、派生クラスが少なくとも1つの仮想関数をオーバーライドする場合に限り、派生クラスは別のバージョンのvtableを必要とします。あなたの例では、Derived仮想関数をオーバーライドしますprintDerivedには独自のバージョンがあるため、vtableprintの対応するエントリはDerivedvtableのエントリとは異なりBaseます。これには通常、の別のvtableが必要になりDerivedます。

何もオーバーライドしなかった場合Derivedでも、正式には別のポリモーフィッククラスになりますが、仮想関数を適切に機能させるために、Basevtableを再利用することもできDerivedます。したがって、技術的には、の個別のvtableは必要ありませんDerived

ただし、実際の実装では、通常「vtable」と呼ばれるデータ構造には、追加のクラス固有の情報も含まれていることがよくあります。その追加情報はクラス固有であるため、同じ仮想関数のセットを使用している場合でも、ほとんどの場合、階層内の異なるクラス間でvtableを共有することは不可能になります。たとえば、一部の実装では、各ポリモーフィックオブジェクトに格納されているvtableポインタは、クラスに関するいわゆる「RTTI情報」も格納しているデータ構造を指します。このため、ほとんどの(すべてではないにしても)実際の実装では、これらのテーブルに格納されている仮想関数ポインターがたまたま同じであっても、各ポリモーフィッククラスは独自のvtableを取得します。

于 2010-01-31T23:05:58.630 に答える