Review虚函数
1. 理解虚函数赖以生存的底层机制:vptr + vtable。虚函数的运行时实现采用了VPTR/VTBL的形式,这项技术的基础:
①编译器在后台为每个包含虚函数的类产生一个静态函数指针数组(虚函数表),在这个类或者它的基类中定义的每一个虚函数都有一个相应的函数指针。
②每个包含虚函数的类的每一个实例包含一个不可见的数据成员vptr(虚函数指针),这个指针被构造函数自动初始化,指向类的vtbl(虚函数表)
③当客户调用虚函数的时候,编译器产生代码反指向到vptr,索引到vtbl中,然后在指定的位置上找到函数指针,并发出调用。
①编译器在后台为每个包含虚函数的类产生一个静态函数指针数组(虚函数表),在这个类或者它的基类中定义的每一个虚函数都有一个相应的函数指针。
②每个包含虚函数的类的每一个实例包含一个不可见的数据成员vptr(虚函数指针),这个指针被构造函数自动初始化,指向类的vtbl(虚函数表)
③当客户调用虚函数的时候,编译器产生代码反指向到vptr,索引到vtbl中,然后在指定的位置上找到函数指针,并发出调用。
2. 对于一个large project,对于一个frequent used unstable class,在其中添加虚函数会带来巨大的编译代价。原理及原因,通过#1,我想应该可以理解充分。解决办法有2:
a. 添加dummyvirtualfunction。占位符的作用。这样,待到确实需要添加虚函数时,只要改名字就行了。由于vptr+vtable的机制是只依赖于vtable中的index而不依赖函数名字的,这就使得:不调用新的虚函数的project不用重新编译了,大大节省编译成本。
b. 使用Pimpl / Bridge pattern 来尽可能不暴露virtual function或者尽可能隐藏实现细节而只把相对稳定的interface暴露给用户。