Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

By building an interface in C first, you will realize that classes in object oriented languages are not doing anything magical, they are just providing syntactic sugar for patterns that are tedious to write in C.

term Syntactic Sugar
Is syntax within a programming language that is designed to make things easier to read or to express. It makes the language “sweeter” for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer. Syntactic sugar is usually a shorthand for a common operation that could also be expressed in an alternate, more verbose, form. [Wikipedia]
Some example of syntactic sugar that all of you are familiar with: x += y; (x = x + y;), foo->bar (*foo).bar

Under the Hood of OOP

In this introductory module, the goal is to simulate an interface and polymorphism using C programming language.

We shall start by explaining what is polymorphism.

What is Polymorphism?

Polymorphism - The “Many Forms” Principle

In C, functions are usually bound at compile-time. If you call calculate_circle_area(), the compiler knows exactly which memory address to jump to. Polymorphism breaks this static link.

unnecessary_info Polymorphism
derived from Greek for “many shapes”

Polymorphism allows a single interface to represent different underlying implementations. E.g. in your C code, this means you can hold a pointer to a generic shape struct, but when you call area(shape), the program decides at runtime whether to execute the circle logic or the square logic.

Function Pointers

Pillar of Dynamic Dispatch

In C, a function pointer is a variable that stores the memory address of a function. This allows you to decide at runtime which function to call. Its syntax is a bit messy but you will get it after writing a few function pointers.

Syntax Reference:

// Declaring a function pointer
double (*operation)(double, double);

// Assigning a function to it
double add(double a, double b) { return a + b; }
operation = add;

// Calling through the pointer
double result = operation(5.0, 3.0);  // Calls add(5.0, 3.0)

We put parenthesis to distinguish return type from function pointer syntax:

// concatenate_arrays variable is a pointer to a function that returns an int
// pointer
int *(*concatenate_arrays)(int *arr1, int *arr2, int size1, int size2);

The key insight: function pointers let you treat functions as variable. You can pass them around, store them in structs, and decide which one to call based on runtime conditions.

Here is a quick reference for function pointers.


Enough introduction. Now you need to implement a dynamic dispatch logic to practice OOP logic - with what you have already known.