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需要某种时髦的预处理器技巧,如果它可以完成的话。