Skip to content

Instantly share code, notes, and snippets.

@InNoHurryToCode
Last active August 10, 2018 04:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save InNoHurryToCode/24836f8672be14672a90ed2e37cafec2 to your computer and use it in GitHub Desktop.
Save InNoHurryToCode/24836f8672be14672a90ed2e37cafec2 to your computer and use it in GitHub Desktop.
Object-Oriented Programming in C

Object-Oriented Programming in C

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.

Table of Contents

  1. Inheritance
  2. Member hiding
  3. Method overloading

1. Inheritance

<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;
}

2. Member hiding

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);
}

3. Method overloading

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);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment