含有virtual函数的类对象包含了一个指针,我们可以从小的方面证明一下。
图中两个类基本一样,只不过child类多了一个virtual而已,现在运行如下程序。
那对象大小会不会因为类中包含多个virtual函数而变大呢?看下面例子:
可见b比a只多了4个字节,不论类中virtual函数多少,而一个指针的大小恰好是4个字节,所以可以判定含有virtual函数的对象包含了一个指针,它通常被缩写为vptr。
这个指针指向了一个虚函数表(virtual function table),简称vtbl。每个类都有只属于自己的一个vtbl,vtbl中包含了父类中没有被子类重定义的virtual函数的地址,以及属于子类自身的对父类的virtual函数重定义的virtual函数地址还有子类独有的virtual函数地址等。并且这个vtbl会随着类中virtual函数的增加而变大。Vtbl实质上是一个数组。
虚函数的执行按照如下步骤进行。首先根据动态绑定原则判断该用哪个vptr,一般都是等号右边的对象的。在该对象所属的vtbl中通过vptr找到合适的函数来执行。
使用virtual函数是需要一点开销的,包括如下几个方面。
1、每个对象包含一个指向vtbl的vptr指针;
2、编译器必须为类生成一个vtbl;
3、每当调用一个virtual函数,编译器必须花点时间去查找合适的函数。