我通过使用多态性(在 C 中)中描述的虚拟表来利用 C 中的多态性,它工作得很好。
不幸的是,我当前项目的限制不允许我在代码的某些部分中使用函数指针或对结构的引用。因此,我不能直接使用原始方法。
在上述方法中,基“类/结构”有一个指向虚拟表的成员。为了得到这个指针,我决定用一个枚举替换它,作为访问虚拟表的键。
它有效,但我想知道是否是最好的解决方案。你有没有比我的建议更适合的替代方案?
/**
* This example shows a common approach to achive polymorphism in C and an
* alternative that does NOT include a reference to function pointer in the
* base
* class.
**/
#include<stdio.h>
// some functions to make use of polymorphism
void funBase1()
{
printf("base 1 \n");
}
void funBase2()
{
printf("base 2 \n");
}
void funDerived1()
{
printf("derived 1 \n");
}
void funDerived2()
{
printf("derived 2 \n");
}
// struct to host virtual tables
typedef struct vtable {
void (*method1)(void);
void (*method2)(void);
}sVtable;
// enumerate to access the virtual table
typedef enum {BASE, DERIVED} eTypes;
// global virtual table used for the alternative solution
const sVtable g_vtableBaseAlternative[] = {
{funBase1, funBase2},
{funDerived1, funDerived2}, };
// original approach that i cannot use
typedef struct base {
const sVtable* vtable;
int baseAttribute;
}sBase;
// alternative approach
typedef struct baseAlternative {
const eTypes vtable_key;
int baseAttribute;
}sBaseAlternative;
typedef struct derived {
sBase base;
int derivedAttribute;
}sDerived;
// original way to use
static inline void method1(sBase* base)
{
base->vtable->method1();
}
const sVtable* getVtable(const int key, const sVtable* vTableDic)
{
return &vTableDic[key];
}
// Alternative to get a reference to the virtual table
static inline void method1Aternative(sBaseAlternative* baseAlternative)
{
const sVtable* vtable;
vtable = getVtable(baseAlternative->vtable_key, g_vtableBaseAlternative);
printf("alternative version: ");
vtable->method1();
}
int main() {
const sVtable vtableBase[] = { {funBase1, funBase2} };
const sVtable vtableDerived[] = { {funDerived1, funDerived2} };
sBase base = {vtableBase, 0 };
sBase derived = {vtableDerived, 1 };
sBaseAlternative baseAlternative = {DERIVED, 1 };
method1(&base);
method1(&derived);
method1Aternative(&baseAlternative);
}