まず、次の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バイト大きいのはそのためです。