0

I've recently took it upon myself to implement classes (polymorphism and all) into C. That is -- implement a data structure that has its own methods, can inherit other such structures and (because of its inheritance) can be type targeted as one of its ancestors.

As you might've guessed, I'm using structs as classes. I'm using function pointers to emulate methods, though they still require manually passing this to them. In order to emulate inheritance, I've decided to #pragma pack(8) all my classes and then copy-paste the inherited class' fields into the child class:

#define _Entity_Content int id;\
                        char *name;
#define inherits(x) _ ## x ## _Content

Let Y inherit X. When passing this to a method of X, from Y, I would pass a pointer to Y. With the #pragma pack(8), this would work once, as any subsequent inheriting would break the simple &myclass notation. A solution would be to calculate offsets for the beginnings of each class (perhaps with pack(1)).

Another, and more important issue, is that, while all this would be possible, would be inconvinient for the user, as well as just plain ugly (having to #define the contents of each struct, etc.)

This what I have currently:

#define _Person_ char *name;\
                 int age;\
                 char *(*getName)(struct Person *);\
                 void (*incrementAge)(struct Person *);
#define superclass(identifier) _ ## identifier ## _

#pragma pack(8)
struct Person {
    superclass(Person);
};

#pragma pack(8)
struct Man {
    superclass(Person);
    struct Person *family;
};

// let man be struct Man
man.incrementAge(&man);

And in an ideal world:

#pragma pack(8)
class(Person, char *name;
              int age;
              etc.
     );

#pragma pack(8)
superclass(Person)
class(Man, struct Person *family;);

What are some tricks I can use to further polish the user experience, as this is what the main goal of my project is?

diingus
  • 9
  • 2
  • 3
    Sorry if this sounds blunt, but trying to invent OO features on top of C has been done numerious times before, and it has never been pretty. You can do basic OO with C, but anything more complex like inheritance and polymorphism simple won't ever be practical to use. If you need advanced OO features, you should consider using language that has already solved most those problems. – user694733 Apr 03 '19 at 11:28
  • 1
    @Someprogrammerdude single `_` are OK, double ones are reserved for implementation – diingus Apr 03 '19 at 11:41
  • if you want to use polymorphism you can look at [this answer](https://stackoverflow.com/questions/524033/how-can-i-simulate-oo-style-polymorphism-in-c) see also [Can you write OO in C](https://stackoverflow.com/questions/351733/can-you-write-object-oriented-code-in-c) and [Oriented Object in C](https://stackoverflow.com/questions/415452/object-orientation-in-c) – Guillaume D Apr 03 '19 at 12:15
  • In order to polish the user experience you may just use C++ :P Jokes aside, you might be interested in the gcc `__attribute__((packed))` since it is safer than your `#pragma pack`, which could be ignored by the compiler. You might also check this related [question](https://stackoverflow.com/questions/28968515/is-it-safe-to-cast-a-c-struct-to-another-with-less-elements). – Josu Goñi Apr 04 '19 at 07:20

0 Answers0