Object-Oriented C Programming
Copyright (C) 2008,2015 by Zack Smith
All rights reserved.
IntroductionObject-oriented programming languages (OOPLs) became dominant a couple decades ago over older procedural languages like C, Pascal and the like. With these languages come fundamental problems and complexities that are not necessarily desired by a software architect.
The case of C++ exemplifies the pitfalls of using OO languages: its templates and multiple inheritance and ever-shifting class libraries make software design, implementation, and debugging more difficult than it needs to be. OOP was never meant to be as much of a mess as C++. While some C++ code is well-written, some C++ code is an illegible tangle of derived classes worse than any "goto" based spaghetti code from the dawn of computing. And yet, nevertheless a typical C++ partisan will defend such a C++ tangle as being perfectly valid and appropriate. Of course he would: Personal job security is the only motive to supporting such gunk.
Due to the problems of common some object-oriented languages, it is sometimes preferable for a programmer to use a non-OOP language such as C augmented to use object-oriented practices.
Key techniques of object-oriented C programming
Struct with pointersA simple technique for implementing an object in C is to imitate C++, and provide a struct with pointers to methods inside.
Struct and message-passerA better alternative is to use an approach similar to Objective C's, and pass messages to objects based on a method name.
An advantage to this approach is that method pointers are less likely to be overwritten since they are not in the data struct.
This approach can also be extended to include the hashing of object data, to provide further protection against program errors.
A further refinement might be to include some non-textual predefined numeric method names, e.g. implemented using enum or #define, which index into a table to avoid doing any string comparison. For instance:
Container classesIn C++, the template functionlity permits the creation of containers of objects, for instance an ordered list of string objects. However the use of templates can quickly make code unreadable.
In C, an equivalent functionality can be implemented by simply having all containers deal with only one object type, which is a 32-bit or 64-bit value, and by providing the container with any functions that it may need to process that value, e.g. to compare two of them in order to sort a list. The application logic would then have to deal with the values themselves to decide if it is a basic type, e.g. int or float, or an object pointer.
An alternative is to literally pound-define
the type in question e.g. #define SOMETYPE int, just before pound-including
the container class, e.g.
write the container class to contain things of type SOMEOBJECT,
which is defined in another file.