Inheritance in C with composition: solved exercise
If you are searching for inheritance in C, the practical approach is composition plus function pointers, since C has no native inheritance model.
This pattern lets you model simple hierarchies and runtime behavior in plain C.
Problem statement
Model a basic hierarchy:
- base type
Animalwith name andspeakbehavior, DogandCattypes that extendAnimalthrough composition,- iterate over an
Animal*array and execute polymorphic behavior.
C solution
#include <stdio.h>
typedef struct Animal Animal;
typedef void (*SpeakFn)(const Animal *);
struct Animal {
const char *name;
SpeakFn speak;
};
typedef struct {
Animal base;
int energy;
} Dog;
typedef struct {
Animal base;
int lives;
} Cat;
void dog_speak(const Animal *a) {
const Dog *d = (const Dog *)a;
printf("Dog %s: woof (energy=%d)\n", d->base.name, d->energy);
}
void cat_speak(const Animal *a) {
const Cat *c = (const Cat *)a;
printf("Cat %s: meow (lives=%d)\n", c->base.name, c->lives);
}
Dog dog_create(const char *name, int energy) {
Dog d;
d.base.name = name;
d.base.speak = dog_speak;
d.energy = energy;
return d;
}
Cat cat_create(const char *name, int lives) {
Cat c;
c.base.name = name;
c.base.speak = cat_speak;
c.lives = lives;
return c;
}
int main(void) {
Dog d = dog_create("Toby", 80);
Cat c = cat_create("Misu", 9);
Animal *group[] = {(Animal *)&d, (Animal *)&c};
int n = (int)(sizeof(group) / sizeof(group[0]));
for (int i = 0; i < n; i++) {
group[i]->speak(group[i]);
}
return 0;
}Expected output
Dog Toby: woof (energy=80)
Cat Misu: meow (lives=9)Common mistakes
- Copying only the base type instead of using pointers to composed objects.
- Forgetting to initialize the function pointer.
- Casting between incompatible types.
- Trying to replicate full OOP inheritance complexity in C when not needed.
Practical use
This pattern is useful for:
- callback-driven engines and libraries,
- plugin systems with a shared interface,
- reducing coupling across modules.
It is a practical design skill for systems-level C code.
Recommended next exercise
- Classes in C with struct: solved modular design exercise
- Struct in C: solved exercise with arrays of structures
- Pointer to pointer in C: solved exercise with reference updates
- All C exercises
Guided practice and next step
If you want a complete path with progressive difficulty:
FAQ
Does C have native inheritance?
No. In C, inheritance-like design is simulated with composition, pointers, and function tables or callbacks.
When should I use function pointers?
When you need swappable runtime behavior, such as strategy patterns, callbacks, or driver abstractions.
Can this pattern fully replace OOP?
Not fully. C does not provide all OOP abstractions, but this approach covers many practical modular-design cases.