免责声明:我是C的完全新手,但我一直在玩它试图模仿一些类的功能.好吧,我知道如果我想这样,我应该学习C++,但请考虑以下一点实验.
Schreiner,在使用ANSI-C的面向对象编程一书中提出了一种使用指针在C中获取面向对象特征的方法.我必须承认我只是浏览了这本书,但我不太喜欢他的方法.基本上,他使用函数指针来安排
func(foo);
Run Code Online (Sandbox Code Playgroud)
实际上导致了呼唤
foo.methods->func();
Run Code Online (Sandbox Code Playgroud)
哪个foo.methods
是包含函数指针的结构.在这种方法中我不喜欢的是,foo
无论如何必须具有全局功能; 也就是说,方法没有被它们所居住的类命名.我的感觉是这很快就会导致混乱:想想两个对象,foo
并且bar
都有一个方法func
但参数数量不同.
所以我试图找到更符合我口味的东西.第一次尝试是以下(我为了简洁省略了声明)
#include <stdio.h>
//Instances of this struct will be my objects
struct foo {
//Properties
int bar;
//Methods
void (* print)(struct foo self);
void (* printSum)(struct foo self, int delta);
};
//Here is the actual implementation of the methods
static void printFoo(struct foo self) {
printf("This is bar: %d\n", self.bar);
}
static void printSumFoo(struct foo self, int delta) {
printf("This is bar plus delta: %d\n", self.bar + delta);
}
//This is a sort of constructor
struct foo Foo(int bar) {
struct foo foo = {
.bar = bar,
.print = &printFoo,
.printSum = &printSumFoo
};
return foo;
}
//Finally, this is how one calls the methods
void
main(void) {
struct foo foo = Foo(14);
foo.print(foo); // This is bar: 14
foo.printSum(foo, 2); // This is bar plus delta: 16
}
Run Code Online (Sandbox Code Playgroud)
这是不方便但有点工作.但是,我不喜欢的是你必须明确地将对象本身添加为第一个参数.通过一些预处理器工作,我可以做得更好一点:
#include <stdio.h>
#define __(stuff) stuff.method(* stuff.object)
//Instances of this struct will be my objects
struct foo {
//Properties
int bar;
//Methods
//Note: these are now struct themselves
//and they contain a pointer the object...
struct {
void (* method)(struct foo self);
struct foo * object;
} print;
};
//Here is the actual implementation of the methods
static void printFoo(struct foo self) {
printf("This is bar: %d\n", self.bar);
}
//This is a sort of constructor
struct foo Foo(int bar) {
struct foo foo = {
.bar = bar,
//...hence initialization is a little bit different
.print = {
.method = &printFoo,
.object = &foo
}
};
return foo;
}
//Finally, this is how one calls the methods
void
main(void) {
struct foo foo = Foo(14);
//This is long and unconvenient...
foo.print.method(* foo.print.object); // This is bar: 14
//...but it can be shortened by the preprocessor
__(foo.print); // This is bar: 14
}
Run Code Online (Sandbox Code Playgroud)
这是我能得到的.这里的问题是它不适用于带参数的方法,因为预处理器宏不能采用可变数量的参数.当然,你可以定义宏_0
,_1
等根据参数的个数(直到一个累了),但是这不是一个好办法.
有没有办法改进这一点,让C使用更面向对象的语法?
我应该补充一点,实际上Schreiner比我在他的书中说的要多得多,但我认为基本结构不会改变.