用C编写面向对象代码有哪些方法?特别是在多态性方面。


另请参阅此堆栈溢出问题C中的面向对象。


当前回答

有几种技术可以使用。最重要的是如何分割项目。我们在项目中使用的接口是在.h文件中声明的,对象的实现是在.c文件中。重要的部分是,所有包含.h文件的模块都只将对象视为void *,而.c文件是唯一知道结构内部的模块。

以FOO类为例:

在。h文件中

#ifndef FOO_H_
#define FOO_H_

...
 typedef struct FOO_type FOO_type;     /* That's all the rest of the program knows about FOO */

/* Declaration of accessors, functions */
FOO_type *FOO_new(void);
void FOO_free(FOO_type *this);
...
void FOO_dosomething(FOO_type *this, param ...):
char *FOO_getName(FOO_type *this, etc);
#endif

C实现文件就像这样。

#include <stdlib.h>
...
#include "FOO.h"

struct FOO_type {
    whatever...
};


FOO_type *FOO_new(void)
{
    FOO_type *this = calloc(1, sizeof (FOO_type));

    ...
    FOO_dosomething(this, );
    return this;
}

因此,我明确地将指针指向该模块的每个函数。c++编译器隐式地完成它,而在C中我们显式地将它写出来。

我真的在我的程序中使用了这个,以确保我的程序不是用c++编译的,而且它在我的语法高亮编辑器中有另一种颜色的良好属性。

FOO_struct的字段可以在一个模块中修改,而另一个模块甚至不需要重新编译就仍然可用。

通过这种风格,我已经处理了OOP(数据封装)的很大一部分优点。通过使用函数指针,甚至可以很容易地实现继承之类的东西,但老实说,它真的很少有用。

其他回答

你可能会发现,查看苹果的Core Foundation api集文档会很有帮助。它是一个纯C API,但是许多类型都被桥接到Objective-C对象等价物上。

看看Objective-C本身的设计也会有帮助。它与c++有点不同,对象系统是根据C函数定义的,例如objc_msg_send用于调用对象上的方法。编译器将方括号语法转换为这些函数调用,因此您不必了解它,但考虑到您的问题,您可能会发现了解它在底层是如何工作的很有用。

当然,它不会像使用带有内置支持的语言那样漂亮。我甚至写过“面向对象的汇编程序”。

我认为首先要说的是(至少在我看来)C的函数指针实现真的很难使用。我会跳过一大堆的圆环来避免函数指针…

也就是说,我认为其他人说的很好。你有结构,你有模块,而不是foo->方法(a,b,c),你最终用方法(foo,a,b,c)如果你有一个“method”方法,那么你可以用类型前缀它,所以FOO_method(foo,a,b,c),正如其他人所说…通过良好地使用.h文件,您可以获得私有和公共文件,等等。

现在,有一些事情是这个技巧不能给你的。它不会提供私有数据字段。我认为,这与意志力和良好的编码习惯有关……而且,没有一种简单的方法来继承它。

这些至少是简单的部分……其余的,我认为是90/10的情况。10%的收益需要90%的工作……

当然这是可能的。这就是所有GTK+和GNOME所基于的框架GObject所做的工作。

您可能需要做的一件事是研究X Window的Xt工具包的实现。当然,它已经很老了,但是许多使用的结构都是在传统的c语言中以面向对象的方式设计的。一般来说,这意味着在这里或那里添加一个额外的间接层,并设计相互覆盖的结构。

你真的可以在C语言中以面向对象的方式做很多事情,即使有时感觉,面向对象的概念并没有完全从#include<favorite_OO_Guru.h>的思想中涌现出来。它们确实构成了当时许多公认的最佳实践。面向对象语言和系统只是提炼和放大了当时编程时代精神的一部分。