实验:面向对象的C?

sle*_*ica 5 c macros object

可能重复:
你能用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);
Run Code Online (Sandbox Code Playgroud)

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

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

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

提前致谢!

pax*_*blo 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;
}
Run Code Online (Sandbox Code Playgroud)

这里可以找到更完整的答案.

回应你的评论:

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

你也许是对的.当对于单个类的每个实例都相同时,不必复制该信息.

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

这将节省相当多的空间,以(最小)成本必须进行两级间接调用函数.