C作为面向对象的语言
您是否可以建议C语言的语法以与面向对象语言类似的方式使用它? 我知道它们不能相同,并且C中没有一些关键字,但我想知道是否有办法利用某些方面(如inheritance),即使在C程序中也是如此。
您可以使用常规函数和虚拟表(vtable)实现多态性。 这是一个非常简洁的系统,我发明了(基于C ++)进行编程练习:
构造函数分配内存,然后调用类初始化内存的init函数。 每个init函数还应包含一个静态vtable结构,其中包含虚函数指针(纯虚拟的NULL)。 派生类init函数在执行任何其他操作之前调用超类init函数。
可以通过实现虚函数包装器(不要与vtables指向的函数混淆)创建一个非常好的API,如下所示(如果在标题中执行此操作,请在其前面添加static inline
):
int playerGuess(Player* this) { return this->vtable->guess(this); }
单inheritance可以通过滥用结构的二进制布局来完成:
请注意,多重inheritance更加混乱,因此在层次结构类型之间进行转换时,通常需要调整指针值。
其他类型特定的数据也可以添加到虚拟表中。 示例包括运行时类型信息(例如,类型名称为字符串),链接到超类vtable和析构函数链。 您可能需要虚拟析构函数,其中派生类析构函数将对象降级为其超类,然后递归调用它的析构函数,依此类推,直到到达基类析构函数并最终释放结构。
有GObject库 :
GLIB对象系统或GObject是一个免费软件库(由LGPL提供),它提供了一个便携式对象系统和透明的跨语言互操作性。 GObject旨在直接在C程序中使用,也可以通过绑定到其他语言。
传统的解决方案是函数指针结构。 我强调传统。 我可以告诉你我在PL / I和C年前写过的代码是什么类型,但如果你可以称之为艺术,我就不会主张代表“艺术”的状态。
这有很多变化,下面是一个妥协。
struct SortOfAnAbstractClass { int (*function1)(SortOfAnAbstractClass* this, int arg1, int arg2, char * arg3); void (*function2)(SortOfAnAbstractClass* this, char *arg); }; struct SortOfDerived { struct SortOfAnAbstractClass base; int instanceVariable1; }; SortOfAnAbstractClass getMeOne() { SortOfDerived *d = malloc(sizeof SortOfDerived); memset(d, 0, sizeof SortOfDerived); d->function1 = myf1; d->function2 = myf2; return &d->base; };
然后’myf1’和’myf2’投出’this’参数然后去城里。 您可以将其扩展为更像完整的虚拟调度。
时间迷雾的另一个常见变化:
struct SortOfAClass { void *creatorInfo; int (*function1)(SortOfAnAbstractClass* this, int arg1, int arg2, char * arg3); void (*function2)(SortOfAnAbstractClass* this, char *arg); };
在这个变体中,包含没有inheritance。 派生类每个都将其私有状态放入creatorInfo中自己的对象中。
看一下GObject库: http : //library.gnome.org/devel/gobject/2.22/ 。
在C中进行OO编程有很多变化。我喜欢这样做的方法是为每个头文件定义一个类。 你会注意到一个构造函数new_testclass()
,它只是初始化你的函数指针并返回一个指向已分配的类/结构的指针。 此外,任何函数都会在第一个参数中获取指向该类的指针(c ++的作用,但隐藏)。
testclass.h
#ifndef MALLOC_H #include #endif struct _testclass { int a; int b; int (*sum)(struct _testclass *obj); }; typedef struct _testclass testclass; int f_sum (testclass *obj) { return obj->a + obj->b; } testclass* new_testclass() { testclass *temp; temp = (testclass*)malloc(sizeof(testclass)); temp->sum = &f_sum; return temp; }
然后你可以简单地使用它。
testclass.c
#include #include "testclass.h" int _tmain(int argc, _TCHAR* argv[]) { int result; testclass *testclass1; testclass1 = new_testclass(); testclass1->a = 5; testclass1->b = 8; result = testclass1->sum(testclass1); printf("%d\n",result); free(testclass1); return 0; }
当然,这里缺少面向对象编程的几个重要方面,但这提供了一种简单的基本抽象方法。 我认为inheritance需要某种时髦的预处理器技巧,如果它可以完成的话。