多态性(C中)

可能重复:
如何在C中模拟OO风格的多态?

我试图用我所知道的语言中的例子来更好地理解多态的概念; C中有多态吗?

这是Nekuromento的第二个例子 ,我考虑了面向对象C的习惯用法 :

animal.h

#ifndef ANIMAL_H_ #define ANIMAL_H_ struct animal { // make vtable_ a pointer so they can be shared between instances // use _ to mark private members const struct animal_vtable_ *vtable_; const char *name; }; struct animal_vtable_ { const char *(*sound)(void); }; // wrapper function static inline const char *animal_sound(struct animal *animal) { return animal->vtable_->sound(); } // make the vtables arrays so they can be used as pointers extern const struct animal_vtable_ CAT[], DOG[]; #endif 

cat.c

 #include "animal.h" static const char *sound(void) { return "meow!"; } const struct animal_vtable_ CAT[] = { { sound } }; 

dog.c

 #include "animal.h" static const char *sound(void) { return "arf!"; } const struct animal_vtable_ DOG[] = { { sound } }; 

main.c中

 #include "animal.h" #include  int main(void) { struct animal kitty = { CAT, "Kitty" }; struct animal lassie = { DOG, "Lassie" }; printf("%s says %s\n", kitty.name, animal_sound(&kitty)); printf("%s says %s\n", lassie.name, animal_sound(&lassie)); return 0; } 

这是运行时多态性的一个例子,就像方法解析一样。

C1x添加了通用选择,可以通过宏实现编译时多态性。 以下示例取自C1x April草案,第6.5.1.1节§5:

 #define cbrt(X) _Generic((X), \ long double: cbrtl, \ default: cbrt, \ float: cbrtf \ )(X) 

用于数学函数的类型通用宏已经通过头文件tgmath.h在C99中可用,但是用户无法在不使用编译器扩展的情况下定义自己的宏。

C中运行时多态的几乎所有实现都将使用函数指针,因此这是基本构建块。

这是一个简单的例子,当程序运行时行为根据它的参数而改变时。

 #include  int tripple(int a) { return 3 * a; } int square(int a) { return a * a; } void transform(int array[], size_t len, int (*fun)(int)) { size_t i = 0; for(; i < len; ++i) array[i] = fun(array[i]); } int main() { int array[3] = {1, 2, 3}; transform(array, 3, &tripple); transform(array, 3, &square); size_t i = 0; for (; i < 3; ++i) printf("%d ", array[i]); return 0; } 

使用函数指针,您可以创建虚拟表并使用它来创建将被统一处理的“对象”,但在运行时表现不同。

 #include  struct animal_vtable { const char* (*sound)(); }; struct animal { struct animal_vtable methods; const char* name; }; const char* cat_sound() { return "meow!"; } const char* dog_sound() { return "bark!"; } void describe(struct animal *a) { printf("%s makes \"%s\" sound.\n", a->name, a->methods.sound()); } struct animal cat = {{&cat_sound}, "cat"}; struct animal dog = {{&dog_sound}, "dog"}; int main() { describe(&cat); describe(&dog); return 0; } 

在C中没有对多态性的内在支持,但是有一些设计模式,使用函数指针,基类’类’(结构)强制转换等,它们可以提供动态分派的逻辑等价物。 GTK库就是很好的例子。

我想,你已经检查了维基百科关于多态性的文章。

在计算机科学中,多态性是一种编程语言特性,它允许使用统一接口处理不同数据类型的值。

根据该定义,不,C本身不支持多态性。 例如,没有用于获取数字的绝对值的一般函数( absfabs分别用于整数和双精度)。

如果您还熟悉C ++,请查看OOPinheritance和模板 – 那些是多态的机制。