实验:面向对象的C?

时间:2010-11-05 05:02:16

标签: c object macros

  

可能重复:
  Can you write object oriented code in C?

嗨!

只是为了它的乐趣,我在最后两天一直在尝试用纯C创建一个非常简单,非常简单的对象环境。我一直在用宏,动态链接,类型描述结构和之类的,我到达了以下内容:

string_o str = new(String, "hello world");
list_o list = new(List);

List.pushf(list, str);

printf("In the list: \"%s\"\n",
       String.text(List.popf(list)));

delete(list);
delete(str);

看起来和工作有点好,但我无法找到伪造实例方法的方法。我不能越过Class.function(instance),不能没有功能名称的全局宏替换,这会破坏封装的目的。

同样,这是一个实验,只是为了挑战和乐趣=)。你能帮我找出办法吗?我不想使用额外的预处理,只使用普通的C和GCC宏。

编辑>忘了说 - 我不希望每个实例都在其结构中包含函数指针。这会给我方法语法好,但这意味着一个4字节的数据对象会有十几个函数指针复制到每个实例。这有点像作弊= P哈哈

提前致谢!

1 个答案:

答案 0 :(得分:12)

C中的面向对象通常使用函数指针完成。这意味着一个结构不仅包含实例的数据,还包含要调用的函数。

这是在C中进行继承和多态的最简单方法。举例来说,这是一个面向对象的通信示例。

它只有一个方法open,但您可以看到TCP和HTML子类的不同之处。通过设置一个特定于类的函数的初始化例程,您将获得多态性。

#include <stdio.h>

// The top-level class.

typedef struct _tCommClass {
    int (*open)(struct _tCommClass *self, char *fspec);
} tCommClass;

// Function for the TCP class.

static int tcpOpen (tCommClass *tcp, char *fspec) {
    printf ("Opening TCP: %s\n", fspec);
    return 0;
}
static int tcpInit (tCommClass *tcp) {
    tcp->open = &tcpOpen;
    return 0;
}

// Function for the HTML class.

static int htmlOpen (tCommClass *html, char *fspec) {
    printf ("Opening HTML: %s\n", fspec);
    return 0;
}
static int htmlInit (tCommClass *html) {
    html->open = &htmlOpen;
    return 0;
}

// Test program.

int main (void) {
    int status;
    tCommClass commTcp, commHtml;

    // Same base class but initialized to different sub-classes.
    tcpInit (&commTcp);
    htmlInit (&commHtml);

    // Called in exactly the same manner.

    status = (commTcp.open)(&commTcp, "bigiron.box.com:5000");
    status = (commHtml.open)(&commHtml, "http://www.microsoft.com");

    return 0;
}

可以找到更完整的答案here

回应你的评论:

  

我不希望每个实例中包含的函数。

你可能是对的。如果对于单个类的每个实例都相同,则不必复制该信息。

有一个简单的方法。您不是让每个实例都携带自己的一组函数指针,而是创建一个为该类保存它们的结构,然后每个实例都获得一个指向该结构的指针。

这样可以节省相当多的空间,只需花费两个级别的间接来调用一个函数。(/ p>