在《 C++ 编程思想》一书中对虚函数的实现机制有详细的描述,一般的编译器通过虚函数表,在编译时插入一段隐藏的代码,保存类型信息和虚函数地址,而在调用时,这段隐藏的代码可以找到和实际对象一致的虚函数实现。
我们在这里提供一个 C 中的实现,模仿 VTABLE 这种机制,但一切都需要我们自己在代码中装配。
之前在网上看到一篇描述 C 语言实现虚函数和多态的文章,谈到在基类中保存派生类的指针、在派生类中保存基类的指针来实现相互调用,保障基类、派生类在使用虚函数时的行为和 C++ 类似。我觉得这种方法有很大的局限性,不说继承层次的问题,单单是在基类中保存派生类指针这一做法,就已经违反了虚函数和多态的本意——多态就是要通过基类接口来使用派生类,如果基类还需要知道派生类的信息……。
我的基本思路是:
- 在“基类”中显式声明一个 void** 成员,作为数组保存基类定义的所有函数指针,同时声明一个 int 类型的成员,指明 void* 数组的长度。
- “基类”定义的每个函数指针在数组中的位置、顺序是固定的,这是约定,必须的
- 每个“派生类”都必须填充基类的函数指针数组(可能要动态增长),没有重写虚函数时,对应位置置 0
- “基类”的函数实现中,遍历函数指针数组,找到继承层次中的最后一个非 0 的函数指针,就是实际应该调用的和对象相对应的函数实现
好了,先来看一点代码:
struct base {
void ** vtable;
int