まず、次のC++のコードを見てください。
#include<stdio.h> class ClassA{ int a; int f(); int g(); }; class ClassB{ int a; virtual int f(); virtual int g(); }; int main(void) { printf("sizeof(ClassA) = %d\n", sizeof(ClassA)); printf("sizeof(ClassB) = %d\n", sizeof(ClassB)); return 0; }
これを実行すると次のような結果になります。(Visual C++, 32bit環境の場合)
sizeof(ClassA) = 4 sizeof(ClassB) = 8
ClassAは仮想関数を持たないクラスです。仮想関数を持たないとは、関数のオーバーライドがないということであり、動的ポリモーフィズムがないということです。このとき、クラスのデータサイズはメンバ変数の合計サイズとなります。
いっぽう、ClassBは仮想関数を持つクラスです。仮想関数を持つとは、関数のオーバーライドがあるということであり、動的ポリモーフィズムがあるということです。この仕組みの実装には一般的には仮想関数テーブルが用いられています。仮想関数を持つクラスは仮想関数テーブルへのポインタを隠しメンバとして持ちます。上の例で、ClassBのサイズがClassAより4バイト大きいのはそのためです。