虚拟表是函数指针的数组。我如何实现它,因为每个函数都有不同的签名?
答案 0 :(得分:4)
你没有实现它。
编译器生成它(或具有相同功能的东西),并且它不受类型系统的约束,因此它可以简单地存储函数地址并生成正确调用它们所需的任何代码。
使用包含不同类型的函数指针的struct
而不是数组,可以实现一些模糊相似的东西。这是在C中实现动态多态的一种常见方式;例如,Linux内核通过定义以下行的接口为文件类对象提供多态行为:
struct fileops {
int (*fo_read) (struct file *fp, ...);
int (*fo_write) (struct file *fp, ...);
// and so on
};
答案 1 :(得分:0)
如果虚拟表中的函数具有不同的签名,则必须将其实现为包含具有异构类型的成员的结构类型。
或者,如果您有其他信息告诉您签名是什么,您可以将函数指针转换为另一个函数指针类型,只要您在调用之前将其强制转换回正确的类型。
答案 2 :(得分:0)
如果您在编译时知道每个函数,那么您可以使用不同类型的函数指针的结构(但是,如果您在编译时知道每个函数,为什么不使用具有虚方法的类?)。
如果你想在运行时这样做,那么void*
的数组就足够了。在调用它们之前,您需要在存储它们时将指针强制转换为(以正确的类型)。当然,您需要在其他地方跟踪函数类型(包括调用约定)。
在不知道你打算用这个做什么的情况下,提供一个更有用的答案是非常困难的。
在代码中实现vtables是有正当理由的。它们是一个实现细节,因此您需要针对已知的ABI而不仅仅是'C ++'。我这样做的唯一一次是在运行时动态创建新COM类的实验(COMI对象的ABI指向vtable的指针,该vtable包含遵循__stdcall
调用约定的函数,其中前3个函数实现IUnknown
接口。)