Object-like C structs
While the language isn't object oriented, you can still add some object-like features to your C structs, such as subclassing, methods and overloading.
If you want to "subclass" the following struct:
typedef struct {
int value;
} base_struct;
You just make a new struct, and add the old one at the top:
typedef struct {
base_struct super;
int value2;
} sub_struct;
You can then cast the new struct to the old to access its members:
sub_struct s;
s.value2 = 13;
((base_struct)s).value = 37;
Adding "methods" is just a function pointer in a struct:
typedef struct _some_struct {
int value;
void (*set_value)(_some_struct *self, int new_value);
} some_struct;
And calling it:
some_struct *s = {};
s->set_value(s, 42);
This method can always be "overloaded" by just changing the function pointer.
Written by Ulrik Flænø Damm
Related protips
5 Responses
Nice article!
I have also found this http://www.cs.rit.edu/~ats/books/ooc.pdf interesting.
Best Regards
Dandy, but _some_struct *self
in that definition should be a struct _some_struct *self
.
@SaberUK perhaps because you're an embedded designer, and your platform just isn't up to C++. Maybe 20 MHz MCU with 128 k FLASH and 8 k RAM? That's my life. ;-)
Reminds me of the Go type-system:
type Base struct {}
type Sub struct { Base } //type embedding
When I try your example I get this error (gcc):
((base_struct)s).value = 37; // "conversion to non-scalar type requested"
This solution works (with same structs):
sub_struct s;
s.value2 = 13;
base_struct *b;
b = ((base_struct*) &s);
b->value = 43;
printf("%d\n",b->value); //print 43
printf("%d\n",s.value2); //print 13
printf("%p\n",&s); //Points to super base_struct
printf("%p\n",&s.super); //Points to super base_struct
printf("%p\n",&b);
printf("%d",s.super.value); // 43