#include "shape.h" double virtual_area(void *self) { ASSERT_CALL_VIRTUAL_METHOD(); } void virtual_draw(void *self) { ASSERT_CALL_VIRTUAL_METHOD(); } struct _virtual_table *virtual_new(void) { struct _virtual_table *vtb = calloc(1, sizeof(struct _virtual_table)); if (vtb == NULL) { return NULL; } vtb->area = virtual_area; vtb->draw = virtual_draw; return vtb; } #include "rect.h" double shape_area(void *self) { double area = 0; struct _shape *parent = (*(struct _rect **)self)->shape; area = parent->vtb.area(self); // struct _shape *parent = *(struct _shape **)self; // void * pthis = container_of(self, struct _rect, shape); // area = parent->vtb.area(pthis); // struct _rect *pthis = (struct _rect *)parent; // pthis->shape->vtb.draw(self, NULL); return area; } void shape_draw(void *self) { struct _shape *pthis = container_of(self, struct _shape, me); pthis->vtb.draw(pthis); } PRIVATE double _shape_area(void *self) { ASSERT_CALL_VIRTUAL_METHOD(); } PRIVATE void _shape_draw(void *self) { ASSERT_CALL_VIRTUAL_METHOD(); } struct _shape *shape_new(void) { struct _shape *shape = calloc(1, sizeof(struct _shape)); if(shape == NULL) { return NULL; } shape->me = shape; static struct _virtual_table vtb = { .area = (double (*)(void *self))_shape_area, .draw = (void (*)(void *self))_shape_draw }; shape->vtb = vtb; return shape; } #if 0 void shape_free(struct _shape * self) { if (self != NULL) { free(self); } } #endif