[C] possible OOP approach
-
Hi forum, coming from a C# background, I'm now developing an embedded project in Microchip XC32 C. I'd like to retain the blessings of polymorphy, though. And I found [this site](http://gefruckelt.de/programmieren/objektorientierung-in-ansi-c/) promising what I wanted. I'm somewhat sceptical: In the second code example, line 13, there's a variable of type ``class_animal`` being created and returned from the function in line 20. Is that really possible or would I have to settle for ``malloc`` and a pointer to ``class_animal``?
Ciao, luker
-
Hi forum, coming from a C# background, I'm now developing an embedded project in Microchip XC32 C. I'd like to retain the blessings of polymorphy, though. And I found [this site](http://gefruckelt.de/programmieren/objektorientierung-in-ansi-c/) promising what I wanted. I'm somewhat sceptical: In the second code example, line 13, there's a variable of type ``class_animal`` being created and returned from the function in line 20. Is that really possible or would I have to settle for ``malloc`` and a pointer to ``class_animal``?
Ciao, luker
-
Hi forum, coming from a C# background, I'm now developing an embedded project in Microchip XC32 C. I'd like to retain the blessings of polymorphy, though. And I found [this site](http://gefruckelt.de/programmieren/objektorientierung-in-ansi-c/) promising what I wanted. I'm somewhat sceptical: In the second code example, line 13, there's a variable of type ``class_animal`` being created and returned from the function in line 20. Is that really possible or would I have to settle for ``malloc`` and a pointer to ``class_animal``?
Ciao, luker
I've had a quick look, and IMHO the code is severely lacking. Most importantly, the classes are often passed by value instead of by reference. Therefore, every time a hard copy is created. Apart from potential issues regarding performance and memory for more complex object instances, this also means that any code attempting to modify an object using these calls will not work! Example: the destructor code passes the object that is to be destructed by value!? This will allow you to clean up resources such as pointers to allocated secondary objects, but if you're managing something more complex, such as a database connection or file handle, you're going to have severe issues, if you can properly clean this up at all! Similarly, the
sound()
functions create local hard copies of the object that in this case is correctly being passed by reference. Why the author did this is beyond me - it generates needless overhead and ensures that you can not modify the original object. Most importantly, modifying the local copy will not change the behavior of the referenced object that was passed to the function, i. e. the effect of these functions is zero! Also the example main function doesn't show inheritance at all, because it always directly calls the sound() function on the class interface it is created as (e. g. callingdog.sound()
). The only way to prove there is something like virtual inheritance at play is to store thecat
anddog
objects asanimal
references, and call thesound()
function via theanimal
class interface. Without actually trying, I predict however, it won't work, because the "derived"sound()
functions won't be called, and, therefore, the super class won't adjust it's behaviour. Always referencing class objects through pointers would go a long way to fix the code and get it towards what the author originally intended. But that still wouldn't introduce polymorphism or encapsulation.GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
-
Hi forum, coming from a C# background, I'm now developing an embedded project in Microchip XC32 C. I'd like to retain the blessings of polymorphy, though. And I found [this site](http://gefruckelt.de/programmieren/objektorientierung-in-ansi-c/) promising what I wanted. I'm somewhat sceptical: In the second code example, line 13, there's a variable of type ``class_animal`` being created and returned from the function in line 20. Is that really possible or would I have to settle for ``malloc`` and a pointer to ``class_animal``?
Ciao, luker
Hi Lukeer ! Returning a struct is indeed valid C. It's even given as example in section 6.8.6.4 of the C11 standard, which deals with the return statement. The return is done with a dumb bit by bit copy. This works very well for struct composed of fundamental types. But as soon as you have pointers in the struct, you need to be extremely careful about who owns an object and shall invoke (manually) the destructor: there is a high risk of nasty memory deallocation errors here ! The more efficient approach would be to return pointers as you suggested. But then, you'll have a high risk of memory leakage, in case the caller is not interested in the returned value (in other functions than the constructor). The safer way would be to design the API to encourage the caller to provide a pointer to the struture to be used, that he is responsible of (whether it's mallocated or local): class_animal a,*pa; newClassAnimal(&a); // reuse the existing structure pa = newClassAnimal (NULL); // or allocate a new one. // here the caller is aware that he has to manage the object I used very long time ago these kind of structures. The function pointers prove to be very efficient way to implement polymorphism in a non object language like C. However the management of the object has its drawback: no automatic destruction, and hence high risk of leakage for more complex execution flows, and especially if you use setjmp/longjmp.