虚函数带来的成本
1. 类的内存空间增加
- 类一旦声明了虚函数,就必须为这个类耗费一个
vtbl
的空间,且表的大小视虚函数数量而定,每个类的所有对象共享内存中的一个vtbl
2. 对象内存空间增加
-
vtbl
只是虚函数实现机制的一半,只有为每个对象指出vtbl
在哪,才有用,所有对象需要vptr
- 一旦声明了虚函数,每个对象都含有一个隐藏的成员变量
vptr
,所以对象付出额外指针的代价
如果内存不充足:对象不大,内含4bytes的成员变量,但增加一个
vptr
就会使其大小翻倍。
如果内存充足:较大对象较难塞入一个缓存分页(cache page),意味换页活动(paging)可能增加,软件性能降低了。
3. 不能inline
-
inline
意味在编译器将调用端的调用动作被调用函数的函数本体取代, -
virtual
意味着运行期才知道调用哪个函数,编译时编译器并不知道哪个函数该被调用
模拟虚函数的调用过程
C * pC = new C;
pc->func();
- 本质:调用
pc->vptr
所指vtbl
中第i
个条目所指的函数,pc作为this
指针参数
(*pc->vptr[i])(pc); // func在vtbl中的下标为i