C language > Tips & tricks

Simulating OOP programming in plain 'C' with double linked lists.

(1/2) > >>

frankie:
This is an exercise to simulate OOP in plain 'C'.
I used a double linked lists library to show how to hidden data in a standard object, the list element, and how make opaque to the user the list management.
The header file hidden the real definitions of the object and give to the user special variables that avoid direct handling. Only during the compilation of the object sources it shows the real definitions.

Tino:
Hello Frankie,

That´s exactly what i planned to use, thanks for this sample.

I´ve read sometimes the terms "Pseudo OOP", "simulate OOP" ...
.. but i can´t get the point how the results differ ?

I can use it for example as DLL in C++, it works as expected.. why is this not OOP ???
Or does the term mean "its not OOP per Definition but implements parts of it (as C++ does)".. ?

However,
thanks for the hints and the samples.

Tino



Synfire:
Frankie,

Nice download. (thumbs up) :)

Tino,

This project is still heavily procedural programming based, therefore it's not technically "OOP". Objects are formed in a very specific way. The procedures/methods need to become part of the structure so that the procedures and variables become associated with each other as an object. There is a lot more to it than that, but in it's basic form this is what we are looking for in OOP, this is why through inheritance we can share functionality between objects but protect objects from one another when they have no inheritable relation.

Now, is OOP possible in C? Of course! I do OOP in NASM all the time, if I can do it in NASM then it can definitely be done in C. Attached is a CFile demo I did as an example for a friend of mine, this demo doesn't show any advanced stuff like inheritance or anything like that, it uses basic static methods. It's a VERY simple object. But for all intense purposes, it is an object (meaning OOP).

If you want to go beyond my CFile demo, the next step would be to look into creating virtual methods. These aren't hard, but are the basis in which inheritance and multiple inheritance works. To do virtual methods you simply add a void pointer to the beginning of your "class" (struct in our case), then during our initialization routine (before we do anything else) we update that pointer to point to a list of procedures (an array of function pointers). So when you call a virtual method, you are calling on of the elements of this array. And when you change a virtual method (during inheritance) you are modifying this array, or adding to it. The problem with the C implementation is that you are going to have to pass your object pointer on the stack which is against all normal standards from most OOP based languages, like C++. Those languages use the ECX register to pass this value to methods, so if you decide you want to create an object in C then use it from C++, then you are probably going to have to do a little inline assembly, something like:


--- Code: ---CFile *this;
asm (
 push ecx ; save ecx
 mov this, ecx ; update 'this'
);

 // method code ....

asm (
 pop ecx ; restore ecx
);
 return ( this );

--- End code ---

In that example I just returned with the object pointer since many C++ objects tend to do that. As you can see I saved ECX to ensure that it didn't get messed up, then moved it's value into my local variable "this". Doing it that way would make it portable to C++, but also remember that in the initialization code you would need to initialize ECX as well as the return value. But I'm not here to tutor.  :D

The truth is, all he would have to do is organize his procedures into a structure to create static methods; or better yet into an array then in his DblLnkLstCreateList() procedure he could modify a pointer at the beginning of his already present structure (with a new member named virt_tbl) to point to that array, then return the pointer to the structure as he already does. Once he did that it would just be a matter of changing the code to call MyDList->vrt_tbl[APPEND_NODE](lnode); and he would be calling the methods, given that he modified the functions for use with ECX. If not, then the call would still need (MyDList, lnode).

Frankie's code is still procedural coding, but it's really not all that far from OOP. It's more in the "spirit" of OOP than in the practice, which is why I assume he called it "Simulating OOP". ;)

Regards,
Bryant Keller

frankie:
Thanks to all for your comments.
I have to clarify that I really would just simulate some interesting characteristics of OOP, not at all create an OOP. Many times we repeat that we like 'C' because it's more efficient and functional of C++, or at list for basic things like a double linked list manager. For such a simple task imo it's a big time waste to use a full featured OOP, so I would like demonstrate that some usefull properties could be achieved anyway.
Bryant your post is very clear and interesting.

Synfire:

--- Quote ---Bryant your post is very clear and interesting.
--- End quote ---

Many thanks mate. I was just explaining in a little more detail because Tino asked "why is this not OOP". I think your demo is extremely useful. Truth is, full fledged OOP would have been overly wasteful for such a project. If you take into account the initialization code and the code for setting up the object pointers in each method, not to mention the extra time you waste coding that.. Your method is much more optimal as well as practical. I'm not a huge fan of OOP, but I'll use it when it's appropriate. This is one of those cases where a "Simulated OOP" would be better than full fledged OOP would be.

Navigation

[0] Message Index

[#] Next page

Go to full version