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


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


当前回答

面向对象的C,可以做到,我在韩国看过这种类型的代码,这是我多年来见过的最可怕的怪物(这是去年(2007年)我看到的代码)。 所以,是的,这是可以做到的,是的,人们曾经这样做过,甚至在这个时代仍然这样做。但我还是推荐c++或Objective-C,这两种语言都起源于C,目的是用不同的范式提供面向对象。

其他回答

似乎人们正在尝试用C来模仿c++风格。我的观点是,用C来做面向对象的编程实际上就是做面向结构的编程。但是,您可以实现后期绑定、封装和继承等功能。对于继承,在子结构中显式地定义一个指向基结构的指针,这显然是一种多重继承。你还需要确定你的

//private_class.h
struct private_class;
extern struct private_class * new_private_class();
extern int ret_a_value(struct private_class *, int a, int b);
extern void delete_private_class(struct private_class *);
void (*late_bind_function)(struct private_class *p);

//private_class.c
struct inherited_class_1;
struct inherited_class_2;

struct private_class {
  int a;
  int b;
  struct inherited_class_1 *p1;
  struct inherited_class_2 *p2;
};

struct inherited_class_1 * new_inherited_class_1();
struct inherited_class_2 * new_inherited_class_2();

struct private_class * new_private_class() {
  struct private_class *p;
  p = (struct private_class*) malloc(sizeof(struct private_class));
  p->a = 0;
  p->b = 0;
  p->p1 = new_inherited_class_1();
  p->p2 = new_inherited_class_2();
  return p;
}

    int ret_a_value(struct private_class *p, int a, int b) {
      return p->a + p->b + a + b;
    }

    void delete_private_class(struct private_class *p) {
      //release any resources
      //call delete methods for inherited classes
      free(p);
    }
    //main.c
    struct private_class *p;
    p = new_private_class();
    late_bind_function = &implementation_function;
    delete_private_class(p);

用c_compiler main.c inherited_class_1编译。obj inherited_class_2。obj private_class.obj。

因此,我的建议是坚持使用纯C风格,不要试图强行采用c++风格。此外,这种方式也有助于以一种非常干净的方式构建API。

我有点晚了,但我想分享我在这个主题上的经验:我这些天在使用嵌入式的东西,我唯一的(可靠的)编译器是C,所以我想在我用C编写的嵌入式项目中应用面向对象的方法。

到目前为止,我看到的大多数解决方案都大量使用类型转换,因此我们失去了类型安全:如果你犯了错误,编译器不会帮助你。这是完全不能接受的。

我的要求是:

尽可能避免类型转换,这样我们就不会失去类型安全; 多态:我们应该能够使用虚方法,类的用户不应该知道某个特定的方法是否是虚的; 多重继承:我不经常使用它,但有时我确实希望某个类实现多个接口(或扩展多个超类)。

我在本文中详细解释了我的方法:C语言中的面向对象编程;另外,还有一个工具可以自动生成基类和派生类的样板代码。

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

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

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

添加一点OOC代码:

#include <stdio.h>

struct Node {
    int somevar;
};

void print() {
    printf("Hello from an object-oriented C method!");
};

struct Tree {
    struct Node * NIL;
    void (*FPprint)(void);
    struct Node *root;
    struct Node NIL_t;
} TreeA = {&TreeA.NIL_t,print};

int main()
{
    struct Tree TreeB;
    TreeB = TreeA;
    TreeB.FPprint();
    return 0;
}