实验:面向对象的C?

发布于 2024-10-01 05:52:24 字数 783 浏览 1 评论 0原文

可能的重复:
你能用 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哈哈

提前谢谢!

Possible Duplicate:
Can you write object oriented code in C?

Hi!

Just for the fun of it, I've been experimenting these last two days with creating a very simple, very straightforward object environment in pure C. I've been toying around with macros, dynamic linking, type-description structures and the like, and I've arrived at the following:

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);

Looks and works kinda nice, but I can't figure a way to fake instance methods. I can't get past Class.function(instance), not without global macro replacements for function names, which defeats the purpose of encapsulation.

Again, this is an experiment, just for the challenge and the fun =). Can you guys help me figure out a way to do this? I don't want to use additional preprocessing, only plain C and GCC macros.

edit> forgot to say -- I don't want each instance to contain the function pointers in its structure. That would give me method syntax alright, but it would mean that a 4-byte data object would have a dozen function pointers copied over to each instance. That's kinda like cheating =P haha

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雪落纷纷 2024-10-08 05:52:24

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;
}

可以在此处找到更完整的答案。

回复您的评论:

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

你可能是对的。当单个类的每个实例的信息都相同时,就没有必要重复该信息。

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

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

Object orientation in C is normally done with function pointers. That means a structure which contains not only the data for an instance but the functions to call as well.

It's the easiest way to do inheritance and polymorphism in C. By way of example, here's an object-orientd communications example.

It only has one method open but you can see how that differs for the TCP and HTML sub-classes. By having an initialisation routine which sets the a class-specific function, you get polymorphism.

#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;
}

A more complete answer can be found here.

In response to your comment:

I don't want the functions contained in every single instance.

You're probably right. It's unnecessary to duplicate that information when it will be the same for every instance of a single class.

There's a simple way around that. Rather than having every instance carry its own set of function pointers, you create one structure holding them for the class, then each instance gets a pointer to that structure.

That will save quite a bit of space at the (minimal) cost of having to do two levels of indirection to call a function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文