/* oop.c - an experiment in object-oriented programming in C */ /* Jon Mayo - PUBLIC DOMAIN - October 16, 2006 */ /* techniques taken from: * X Intrinsics Toolkit. * Object Oriented Programming with ANSI-C, Axel-Tobias Schreiner. * http://www.cs.rit.edu/~ats/books/index.html * The Xt Intrinsics as a General Purpose Application Development Platform * http://www.thinkbank.com/jordan/papers/USENIX/AppDev.html */ #include #include #include #define MAKE_BASECLASS(c) /* TODO */ #define GET_PARENT_CLASS(o) /* TODO */ #if 1 /* enable magic */ #define USE_MAGIC(x) x #else /* disable magic */ #define USE_MAGIC(x) #endif struct base_object; struct base_class; /*** hidden stuff ***/ struct base_class { USE_MAGIC(unsigned magic); struct base_object *(*ctor)(struct base_object *, va_list ap); void (*dtor)(struct base_object *); size_t instance_size; }; struct base_object { const struct base_class *parent_class; /* IMMUTABLE */ }; /*** exported interface ***/ /* allocate a new instance of a particular class */ void *newObject(struct base_class *the_class, ...) { struct base_object *ret; ret=calloc(1, the_class->instance_size); /* default is to be all zeros */ if(!ret) return 0; ret->parent_class=the_class; if(the_class->ctor) { va_list ap; va_start(ap, the_class); ret=the_class->ctor(ret, ap); va_end(ap); } } void deleteObject(struct base_object *the_object) { const struct base_class *parent_class=the_object->parent_class; if(the_object && parent_class && parent_class->dtor) { parent_class->dtor(the_object); } free(the_object); } size_t sizeofObject(struct base_object *the_object) { return the_object && the_object->parent_class ? the_object->parent_class->instance_size : 0; } /* call the compare interface */ int cmpObject(void *a, void *b) { /* TODO: can I really make a place-holder interface with this technique? */ } /* duplicate an existing object */ void *dupObject(void *the_object) { } /* sets a value, returning the original one */ void *setObject(void *the_object, int offset, void *value) { /* this is a raw interface, deallocation would be handled by the caller */ } /* gets the current value */ void *getObject(void *the_object, int offset) { } #ifdef STAND_ALONE int main() { return 0; } #endif