There are various reasons why one might want to emulate object-oriented programming (OOP) in C. Many could write such code, but only a few will master it. I won't discuss OOP in detail, as there are better resources for this. Thus, I assume that you already have knowledge of OOP and writing in an OOP language. What I will discuss in the document, is a quick rundown of several techniques to emulate OOP in C.
- Inheritance
- Member hiding
- Method overloading
<Something about inheritance by composition, and aliasing>
foo.h
typedef struct foo foo;
struct foo {
int x;
}
void ctor_foo(foo *foo, int x);
foo.c
void ctor_foo(foo *foo, int x) {
foo->x = x;
}
bar.h
typedef struct bar bar;
struct bar {
foo base;
int y;
}
void ctor_bar(bar *bar, int x, int y);
bar.c
void ctor_bar(bar *bar, int x, int y) {
ctor_foo(x);
bar->y = y;
}
foo.h
typedef struct foo foo;
struct foo {
int x;
}
void ctor_foo(foo *foo, int x);
foo.c
void ctor_foo(foo *foo, int x) {
foo->x = x;
}
bar.h
typedef struct bar bar;
struct bar {
foo base;
void *private;
}
void ctor_bar(bar *bar, int x, int y);
void dtor_bar(bar *bar);
bar.c
struct private_bar {
int y;
}
void ctor_bar(bar *bar, int x, int y) {
ctor_foo(&base, x);
bar->private = malloc(typeof(struct private_bar));
bar->(struct private_bar)private->y = y;
}
void dtor_bar(bar *bar) {
free(bar->private);
}
foo.h
typedef struct foo foo;
typedef struct foo_vtbl foo_vtbl;
struct foo {
foo_vtbl vptr;
void *private;
}
struct foo_vtbl {
int (*get_x)(foo *foo);
}
void ctor_foo(foo *foo, int x);
void dtor_foo(foo *foo);
foo.c
struct private_foo {
int x;
}
int get_x(foo *foo) {
return foo->(struct private_foo)private->x;
}
struct foo_vtbl foo_vtable = {
get_x
};
void ctor_foo(foo *foo, int x) {
foo->vptr = &foo_vtable;
foo->private = malloc(typeof(struct private_foo));
foo->(struct private_foo)private->x = x;
}
void dtor_foo(foo *foo) {
free(foo->private);
}
bar.h
typedef struct bar bar;
typedef struct bar_vtbl bar_vtbl;
struct bar {
foo base;
bar_vtbl vptr;
void *private;
}
struct bar_vtbl {
int (*get_x)(bar *bar);
int (*get_y)(bar *bar);
}
void ctor_bar(bar *bar, int x, int y);
void dtor_bar(bar *bar);
bar.c
struct private_bar {
int y;
}
int get_x(bar *bar) {
return bar->base->vptr->get_x(bar->base);
}
int get_y(bar *bar) {
return bar->(struct private_bar)private->y;
}
struct bar_vtbl bar_vtable = {
get_x,
get_y
};
void ctor_bar(bar *bar, int x, int y) {
ctor_foo(&base, x);
bar->vptr = &bar_vtable;
bar->private = malloc(typeof(struct private_bar));
bar->(struct private_bar)private->y = y;
}
void dtor_bar(bar *bar) {
free(bar->private);
}