4

我知道,因为 C 不是面向对象的,所以我们最接近方法的是在结构中使用函数指针。这只是一个思考练习,但是否有可能:

list.add(void* data)

没有将列表本身作为参数传递

我知道:

list.add(list_t* list, void* data)

很容易实现,但是有什么方法可以使用 C 的任何部分以这种方式模拟方法吗?

我知道答案可能是否定的,但如果可以的话,请向我解释!谢谢。

4

4 回答 4

6

这是我使用可变参数宏(C99) 得到的最漂亮的语法:

#define call(obj, method, ...) ((obj).method(&(obj), __VA_ARGS__))

用法(点击查看ideone)

struct class {
    int a;
    int (*method)(struct class* this, int b, int c);
};

int code(struct class* this, int b, int c) {
    return this->a*b+c;
}

struct class constructor(int a) {
    struct class result = {a, code};
    return result;
}

#define call(obj, method, ...) ((obj).method(&(obj), __VA_ARGS__))

#include <stdio.h>
int main() {
    struct class obj = constructor(10);
    int result = call(obj, method, 2, 3);
    printf("%d\n", result);
    return 0;
}
于 2013-06-27T08:39:33.103 回答
2

不仅是实例方法,你甚至可以使用正确的库来拥有 CLOS 风格的泛型方法。Laurent Deniau 的 COS 库(另见论文:[链接])提供了一个完整的 OO 系统,您可以#include立即开始使用;方法语法并不比任何其他函数调用重。

它显然也很快。作者声称已经在 Objective-C 中表达的类似代码上获得了性能优势(我会对这个声明本身持怀疑态度,但即使它们具有可比性,这也令人印象深刻)。

于 2013-06-28T00:56:50.650 回答
1

要模拟 OO 方法调用,您需要具有类或 vtable 指针的对象。例如,如果您list_t包含一个funcs指向包含函数指针的结构的成员,其中之一是add,那么您的用法将是

list->funcs->add(list, data)

您可以在可变参数宏中捕获:

#define OO(obj, func, ...) (obj)->funcs->func(obj, __VA_ARGS__)

OO(list, add, data);
于 2013-06-27T09:18:09.660 回答
0

如果你想要一些简单的东西,你可以使用块语言扩展来实现结构成员函数。在这里写博客。

您可以使用块来 lambda 捕获关联的结构,模拟this指针。

这种方法没有虚拟分派,因此是否考虑这些真实对象取决于您。

于 2013-06-28T01:53:30.053 回答