我知道,因为C不是面向对象的,所以我们最接近方法的是在结构中使用函数指针。这只是一个思考练习,但有可能有:
list.add(void* data)
没有将列表本身作为参数传递?
我知道:
list.add(list_t* list, void* data)
很容易实现,但有没有办法,使用C的任何部分,以这种方式模拟一个方法?
我认识到答案可能是否定的,但如果可以,请向我解释!感谢。
答案 0 :(得分:6)
这是我使用可变参数宏(C99)获得的最漂亮的语法:
#define call(obj, method, ...) ((obj).method(&(obj), __VA_ARGS__))
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;
}
答案 1 :(得分:2)
不仅是实例方法,而且您甚至可以使用正确的库具有CLOS样式的泛型方法。 Laurent Deniau's COS library(另见论文:[link])提供了一个完整的OO系统,您可以#include
并立即开始使用;方法语法并不比任何其他函数调用重。
它显然也很快;作者声称在Objective-C中表达的类似代码已经获得了性能优势(我会用一小撮盐来宣称自己,但即使它们具有可比性,令人印象深刻)。
答案 2 :(得分:1)
要模拟OO方法调用,您需要具有class或vtable指针的对象。如果您的list_t
包含一个指向包含函数指针的结构的funcs
成员,其中一个是add
,那么您的用法将是
list->funcs->add(list, data)
您可以在可变参数宏中捕获:
#define OO(obj, func, ...) (obj)->funcs->func(obj, __VA_ARGS__)
OO(list, add, data);
答案 3 :(得分:0)
如果您想要简单的东西,可以使用blocks语言扩展来实现struct成员函数。博客here。
您可以使用块来捕获关联的结构,模拟 this 指针。
这种方法没有虚拟调度,因此您是否考虑这些真实对象取决于您。