Object-oriented design patterns

16 points by kaycebasques


lor_louis

One thing I like doing whenever I build vtables by hand is to always have the vtable struct as the first member of the object.

struct vtable {...};

struct obj_a {
    struct vtable vtable;
    char *name;
};

struct obj_b {
  struct vtable vtable;
  int count;
};

This way I can easily build generic functions which only require a pointer to the vtable since &obj_a == &obj_a.vtable

void do_generic(struct vtable *obj) {
    obj->do(obj);
};
...
do_generic(&obj_a);

It’s not super type safe and you might have to define your member functions as always taking void* as the first parameter but it’s pretty ergonomic.

The alternative looks like:

void do_generic2(void *obj, struct vtable *vtable) {
    vtable->do(obj);
}
...
do_generic2(&obj_a, &obj_a.vtable);
madhadron

Don Box’s book ‘Essential COM’ goes way further down this path for folks that are interested.

icefox

“Object oriented” code is just the combination of three other features: Dynamic dispatch, subtyping (inheritance), and namespacing. There’s no particular reason they should go together; it’s just easy to implement them with pointers and vtables in a way that gets you Smalltalk or Java. For example this implementation basically leaves out subtyping.