Polymorphism (in C)

Possible duplicate:
How to model OO-style polymorphism in C?

I am trying to better understand the idea of ​​polymorphism with examples from languages ​​that I know; Is polymorphism in C?

+8
c polymorphism oop
source share
5 answers

This is the second Nekuromento example factorized in a way that I find idiomatic for object-oriented 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 <stdio.h> 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; } 

This is an example of run-time polymorphism that occurs when a method resolves.

C1x added a generic choice that makes macro-compilation time polymorphism possible. The following example is taken from the C1x April project, section 6.5.1.1 §5:

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

Type-based macros for mathematical functions were already available on C99 through the tgmath.h header, but users were unable to define their own macros without using compiler extensions.

+28
source share

Almost all implementations of C run-time polymorphism will use function pointers, so this is the main building block.

Here is a simple example where the behavior of a procedure executable changes depending on its argument.

 #include <stdio.h> 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; } 

Using function pointers, you can create virtual tables and use them to create “objects” that will be processed evenly, but behave differently at runtime.

 #include <stdio.h> 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; } 
+9
source share

There is no built-in support for polymorphism in C, but there are design patterns using function pointers, base classes (structures), etc. that can provide the logical equivalent of dynamic dispatch. A good example is the GTK library .

+3
source share

I think you have already checked the Wikipedia article on polymorphism .

In computer science, polymorphism is a function of a programming language that allows you to process the values ​​of different types of data using a uniform interface.

According to this definition, no, C does not support polymorphism. For example, there is no general function to get the absolute value of a number ( abs and fabs for integers and doubles, respectively).

If you are also familiar with C ++, look at inheritance and OOP patterns - these are mechanisms for polymorphism.

+1
source share
0
source share

All Articles