用类加入C

免责声明:我是C的完全新手,但我一直在尝试模仿一些类的function。 好吧, 我知道如果我想这样做,我应该学习C ++,但请考虑以下一点实验

Schreiner,在使用ANSI-C的面向对象编程一书中提出了一种使用指针在C中获取面向对象特征的方法。我必须承认我只是浏览了这本书,但我不太喜欢他的方法。 基本上,他使用函数指针来安排

func(foo); 

实际上导致了呼唤

 foo.methods->func(); 

其中foo.methods是一个包含函数指针的结构。 在这种方法中我不喜欢的是,无论如何必须拥有全局函数foo ; 也就是说,方法没有被它们所居住的类命名。我的感觉是这很快就会导致混乱:想想两个对象foobar ,它们都有方法func但参数数量不同。

所以我试图找到更符合我口味的东西。 第一次尝试是以下(为了简洁我省略了声明)

 #include  //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 } 

这是不方便的,但有点工作。 但是,我不喜欢的是你必须明确地将对象本身添加为第一个参数。 通过一些预处理器工作,我可以做得更好一点:

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

这是我能得到的。 这里的问题是它不适用于带参数的方法,因为预处理器宏不能采用可变数量的参数。 当然可以根据参数的数量定义宏_0_1等等(直到一个人累了),但这不是一个好方法。

有没有办法改进这一点,让C使用更面向对象的语法?

我应该补充一点,实际上Schreiner比我在他的书中说的要多得多,但我认为基本结构不会改变。

各种框架已经存在。 例如,参见http://ldeniau.web.cern.ch/ldeniau/html/oopc.html

一本解释如何操作的书(PDF格式)是ANSI C中的面向对象编程 (1993),但仍然包含一些有效的想法和提示,恕我直言。

你有没看过谷歌的Go? 它基本上是一个现代化的C,其中的事情按照你建议的方式完成。 它具有参数多态性。 所以你不必这样做:

 static void printFoo(struct foo self) { printf("This is bar: %d\n", self.bar); } 

在Go中,它可以这样做:

 static void print(Foo self) { printf("This is foo: %d\n", self.foo); } static void print(Bar self) { printf("This is bar: %d\n", self.bar); } 

在Go Foo和Bar也是结构。 所以你基本上和Go语言设计师一样。

有关Go的概述,请参阅http://golang.org/doc/effective_go.html这是Go主要语言描述: http : //golang.org/doc/effective_go.html