Simulating object oriented programming (OOP) in C

Most of the languages support OOP out of the box, but many people are not aware that OOP and even functional programming can be done also in C (even though it is not very practical, unless we use some macros  to hack our way through and make it more convenient by reducing the boilerplate code).

In this tutorial I will provide some insight on how to simulate an object in C language in order to write in OOP style. Before let us review again the definition of a class and object in OOP.


What is a class in OOP ?

A class is a blueprint that describes  the contents of the objects that belong to it. It describes the data fields (also known as instance variables), and defines the operations (functions or methods).

Depending on the programming language, the data fields and operations can have different access modifiers, usually private, protected and public. The role of the access modifiers is to provide a way for the programmer to enforce encapsulation of the data (hiding implementation details from the user).

What is an object in OOP ?

An object in its simplest terms is an instance of a class, a “living” instance of  the blueprint known as class. It contains its own set of instance data fields, and shares the methods with all  the other instances of the same class.

Simulating objects in C

From the definitions above, we realize that we need to find a way to encapsulate related data fields and methods to define a class and then instantiate objects of this particular class.

In C we can group related data fields  by using structures, so this part is already  covered. What is left is to find a way to provide methods to our structures. This can be done by using function pointers.

Let us see an example. I will create a class named Faker, which will be responsible for generating dummy data that are going to be used for testing.

The header file faker.h looks like:

The function newFaker will serve as the constructor, it will be responsible for initializing an instance of the Faker class.

The header serves a very important role:  provides a public interface to the other parts of the system. This means that the implementation is up to us, and we can enforce the encapsulation and hide the way its functionality is implemented (especially the private variables necessary to provide the desired functionality).

The faker implementation file faker.c looks like:

An important point to notice here is how we bind the instance to its methods. We are passing Faker* self to the age method, and then we can access the minAge property.
Another important point to take away is the way we are hiding the implementation details. The variables addressesPool and emailsPool will not be accessible by the clients of the faker.h interface. So we provide the desired functionality, while we hide the implementation details. We can as well compile the faker library to a shared runtime library so the source code will not be visible.

The client of the faker, can look like:

I usually use Faker to seed random users and populate a database, or create random users for testing certain functionalities of my software.
This was just a short introduction to OOP in C.

If you have any questions, feel free to comment below.