Introduction

Inheritance and polymorphism are the most powerful features of Object Oriented Programming Languages. With inheritance and polymorphism, we can achieve code reuse.

There are many tricky ways for implementing polymorphism in C.

The aim of this article is to demonstrate a simple and easy technique of applying inheritance and polymorphism in C. By creating a VTable (virtual Table) and providing proper access between base and derived objects, we can achieve inheritance and polymorphism in C. The concept of VTable can be implemented by maintaining a table of pointers to functions. For providing access between base and derived objects, we have to maintain the references of derived object in the base class and the reference of the base object in the derived class.

Description

Before proceeding to the implementation of inheritance and polymorphism in C, we should know the class representation in C.

Here, the functions defined for the structure Person are not encapsulated. For implementing encapsulation, which is binding between data and functions, pointers to functions are used. We need to create a table of function pointers. The constructor new_Person() will set the values of the function pointers to point to the appropriate functions. This table of function pointers will then act as an interface for accessing the functions through the object.

The new_Person() function acts as a constructor. The function returns the newly created instance of the structure. It initializes the interface of the function pointers to access other member functions. One thing to note here is, we are defining only those function pointers which are available for public access. We have not given access to private functions in the interface. Let us take a look at the new_Person() function or the constructor of our Person class in C.

Note: Unlike in C++, in C, we cannot access data members directly in the functions. In C++, data members can be directly accessed implicitly through the “this” pointer. As we do not have the “this” pointer in C, we pass the object explicitly to the member function. For accessing the data members of a class in C, we need to pass the calling object as an argument to the function. In the above example, we are passing the calling object as a first argument to the function. This way, the function can access the data members of the object.

Representation of the class in C

The Person class representation - check the initialization of the interface to point to the member functions:

Simple example of inheritance and polymorphism

Inheritance - class Employee derived from class Person:

In the above example, class Employee inherits the properties of class Person. As DisplayInfo() and WriteToFile() functions are virtual, we can access the same functions for the Employee object from the Person instance. For this, we need to initiate the Person instance with the Employee class. This is possible because of polymorphism. In the case of polymorphism, to resolve the function call, C++ makes use of the VTable, which is nothing but a table of pointers to functions.

The interface of pointers to functions that we are maintaining in the structure works similar to the VTable.

In C, inheritance can be achieved by maintaining a reference to the base class object in the derived class object. With the help of the base class' instance, we can access the base data members and functions. However, in order to achieve polymorphism, the base class object should be able to access the derived class object’s data. For this, the base class should have access rights to the derived class’ data members.

For implementing the virtual function, the signature of the derived class’ function has to be similar to the base class’ function pointers. That means the derived class function will take the instance of the base class as a parameter. We are maintaining the reference to the derived class in the base class. During function implementation, we can access the actual derived class data from the reference of the derived class.

Equivalent representation in C structures

Inheritance in C - Person and Employee structure in C:

As shown in the diagram, we have declared a pointer in the base class structure holding the derived class object, and a pointer in the derived class structure holding the base class object.

In the base class object, the function pointers point to the virtual functions of its own class. In the derived class object’s construction, we need to make the interface of the base class to point to the member function of the derived class. This gives us the flexibility of calling the derived class function through the base class object (polymorphism). For more details, check the construction on the Person and Employee objects.

When we talk about polymorphism in C++, there is a problem of object destruction. For the proper cleanup of objects, it uses virtual destructors. In C, this can be done by making the delete function pointer of the base class to point to the derived class destructor function. The derived class' destructor cleans up the derived class data as well as the base class data and object. Note: Check the sample source code for details about the implementation of the virtual destructor and the virtual functions.

Note: Changed the pointing position of the interface (VTable) from base class functions to derived class functions. Now we can access the derived class functions from the base class (polymorphism). Let us now look at how we can use polymorphism.

Conclusion

Involving the above described simple addition of code can grant the procedural C language a flavor of polymorphism and inheritance. We simply use function pointers for creating a VTable and maintain cross references of objects for accessibility among base and derived objects. With these simple steps, we can implement Inheritance and Polymorphism in C.

There exists many redundant things.
First of all using the pointer to class.
As you can see, in the function main, calling of member functions means passing a reduntant parameter:

EmployeeObj->Display(EmployeeObj);

In C++ it looks like this:

EmployeeObj->Display();

As you can see, the notation EmployeeObj-> already means passing pointer to EmployeeObj. There is quite no difference between C style Display(EmployeeObj) and C++ style EmployeeObj->Display(). This means exactly the same thing.

Second redundant thing is to initialize class function pointers in the constructor like this:

pObj->Display = Person_DisplayInfo;

Pointers to functions should not be class members. You may initialize them at once before starting the application. Once initialized you can always call C style OOP like this Display(EmployeeObj). You may see a lot of samples like using handles in WINAPI, for example ShowWindow(hWnd, ...).
The polymorphism can be done by using some special kind of members. So, the class will contain a pointer to a structure with pointers to functions. This is named virtual table. You will initialize virtual table for each type of class separately. Or you may use a message handler. Processing a message is equivalent to execution of a virtual function. For instance function WNDPROC in WinAPI is the implementation of the window polymorphism in WinAPI.
The inheritance in the WinAPI can be done by using wndextra/classextra parameters.

- There is no need to store function pointers in the class (structs). Functions are still globally defined and it has performance penalty in contructors and each access, and size penalty for each instantiated object.
- It has circular dependency from base-to-derived, which is not necessary. (which is another size penalty.)
- It does not support casting a derived object to base object.

There are other better implementations in the codeproject or around the net.
It is a good exercise though.

This is pretty useful for academic purpose and maybe for some embedded programming. It's interesting for me in this regard that I can use some of these concepts in C++ too. I can remove over dependance on inheritence and use aggregation instead (e.g, create a person object dynamically inside the employee object). To me, aggregation is a better concept that inheritence in most cases.

An interesting exposee into the implementation of OO in C . I'd have given it a 5 if the article had focussed more upon how C compilers implement OO, rather than how to create a competing solution. Like others, I struggle to see the point of that.
As a minor efficiency point, C will actually generate a real table of pointers, scoped (effectively) as a private static member of the class. Your solution (with the individual member pointers) makes for a more usable solution in C, but is less efficient storage-wise.

One note though, If you're using C++ compiler then you should change "this" in "pData this" to something else, remember that C++ compiler using "this" as its keyword. Therefore it won't compile in C++, but it's save if you're using C compiler.

He means that the function fppmd has to have a reference to the struct to operate on. The function doesn't have member variables because that is not available in C. He didn't mean just naming your variable "this".

void PrintMyData(pData this)
{
//printf function is accessing data member and is using it.
printf("myData value is %d\n", this->myData);
}

In this function, you are still passing the reference to Data object, only the naming convention is changed.

By saying "Functions can't access data members", I mean to say, in C++, the member functions does have the reference to object as argument. Object reference is passed to member function implicitly as "this" pointer. Because of implicit reference to object, member functions can directly access the data members.

However this is not the case in C. We need to pass the object reference to member function explicitly as function argument, so that we can access the data members in the function.

Your article is really nice! It reminds me about GTK+. It is written in C but it has almost all the features of C++ (Inheritance and Polymorphish). However, the functions are not tightly bound to structures using function pointers, that is, you need not call functions using structure pointers like pPersonObj->Display(pPersonObj); where you again need to pass the structure pointer as argument. GTK+ has a bit different approach like:

If you look at the documentation of GTK+ you will notice the inheritance hierarchy of widgets and their assosiated functions. You can have a look at the source code and some tutorials provided for adding new widget classes to GTK to know more about how the inheritance is achieved. I am sure you will be definitely fascinated to see the implementation.

It should be noted that it's also a disaster of a framework/toolkit to program with. And extending controls is a total pain in the ass with it as well. Not fun at all. Trying to force OO concepts into a language that doesn't support them at all is a complete exercise in futility, but more power to you if you're into that kind of thing.