用C编写面向对象代码有哪些方法?特别是在多态性方面。
另请参阅此堆栈溢出问题C中的面向对象。
用C编写面向对象代码有哪些方法?特别是在多态性方面。
另请参阅此堆栈溢出问题C中的面向对象。
当前回答
当然,它不会像使用带有内置支持的语言那样漂亮。我甚至写过“面向对象的汇编程序”。
其他回答
是的,但我从未见过有人尝试用C实现任何类型的多态性。
你可以使用函数指针来伪装它,事实上,我认为理论上可以将c++程序编译成C语言。
然而,将一种范式强加于一种语言,而不是选择一种使用范式的语言,很少有意义。
我有点晚了,但我想分享我在这个主题上的经验:我这些天在使用嵌入式的东西,我唯一的(可靠的)编译器是C,所以我想在我用C编写的嵌入式项目中应用面向对象的方法。
到目前为止,我看到的大多数解决方案都大量使用类型转换,因此我们失去了类型安全:如果你犯了错误,编译器不会帮助你。这是完全不能接受的。
我的要求是:
尽可能避免类型转换,这样我们就不会失去类型安全; 多态:我们应该能够使用虚方法,类的用户不应该知道某个特定的方法是否是虚的; 多重继承:我不经常使用它,但有时我确实希望某个类实现多个接口(或扩展多个超类)。
我在本文中详细解释了我的方法:C语言中的面向对象编程;另外,还有一个工具可以自动生成基类和派生类的样板代码。
是的,你可以。在c++或Objective-C出现之前,人们就开始编写面向对象的C语言了。在某种程度上,c++和Objective-C都试图采用C中使用的一些面向对象概念,并将它们形式化为语言的一部分。
这是一个非常简单的程序,它展示了如何创建一个看起来像方法调用的东西(有更好的方法可以做到这一点。这只是证明语言支持这些概念):
#include<stdio.h>
struct foobarbaz{
int one;
int two;
int three;
int (*exampleMethod)(int, int);
};
int addTwoNumbers(int a, int b){
return a+b;
}
int main()
{
// Define the function pointer
int (*pointerToFunction)(int, int) = addTwoNumbers;
// Let's make sure we can call the pointer
int test = (*pointerToFunction)(12,12);
printf ("test: %u \n", test);
// Now, define an instance of our struct
// and add some default values.
struct foobarbaz fbb;
fbb.one = 1;
fbb.two = 2;
fbb.three = 3;
// Now add a "method"
fbb.exampleMethod = addTwoNumbers;
// Try calling the method
int test2 = fbb.exampleMethod(13,36);
printf ("test2: %u \n", test2);
printf("\nDone\n");
return 0;
}
命名空间通常通过以下方式实现:
stack_push(thing *)
而不是
stack::push(thing *)
要将C结构体变成类似c++类的东西,您可以转向:
class stack {
public:
stack();
void push(thing *);
thing * pop();
static int this_is_here_as_an_example_only;
private:
...
};
Into
struct stack {
struct stack_type * my_type;
// Put the stuff that you put after private: here
};
struct stack_type {
void (* construct)(struct stack * this); // This takes uninitialized memory
struct stack * (* operator_new)(); // This allocates a new struct, passes it to construct, and then returns it
void (*push)(struct stack * this, thing * t); // Pushing t onto this stack
thing * (*pop)(struct stack * this); // Pops the top thing off the stack and returns it
int this_is_here_as_an_example_only;
}Stack = {
.construct = stack_construct,
.operator_new = stack_operator_new,
.push = stack_push,
.pop = stack_pop
};
// All of these functions are assumed to be defined somewhere else
和做的事:
struct stack * st = Stack.operator_new(); // Make a new stack
if (!st) {
// Do something about it
} else {
// You can use the stack
stack_push(st, thing0); // This is a non-virtual call
Stack.push(st, thing1); // This is like casting *st to a Stack (which it already is) and doing the push
st->my_type.push(st, thing2); // This is a virtual call
}
我没有做析构函数或删除,但它遵循相同的模式。
This_is_here_as_an_example_only类似于一个静态类变量——在一个类型的所有实例之间共享。所有的方法都是静态的,除了一些采用this *