diff --git a/main.c b/main.c index 4baddfb..8945162 100644 --- a/main.c +++ b/main.c @@ -98,7 +98,7 @@ struct _rect int invalid; // super - struct _shape shape; + struct _shape *shape; // struct _shape; // struct _virtual_table vtb; @@ -110,20 +110,49 @@ struct _rect // void (*draw)(void *self); }; -double rect_area(struct _rect *self, void *parent) +double rect_area(void *self, void *parent) { - double area = self->width * self->height; + double area = 0; + struct _rect *pthis = (struct _rect *)parent; + area = pthis->shape->vtb.area(self, NULL); + return area; +} + +void rect_draw(void *self, void *parent) +{ + printf("rect draw\n"); +} + +double _rect_area(void *self, void *parent) +{ + struct _rect *pthis = (struct _rect *)self; + double area = pthis->width * pthis->height; + printf("rect area = %0.2f\n", area); return area; } -void rect_draw(struct _rect *self, void *parent) +void _rect_draw(void *self, void *parent) { printf("rect draw\n"); } struct _rect *rect_new(double width, double height) { + // super + static struct _virtual_table vtb = { + .area = (double (*)(void *self, void *parent))_rect_area, + .draw = (void (*)(void *self, void *parent))_rect_draw, + }; + + struct _shape *shape = shape_new(); + if (shape == NULL) + { + return NULL; + } + shape->vtb = vtb; + + // self struct _rect *rect = calloc(1, sizeof(struct _rect)); if (rect == NULL) { @@ -131,14 +160,9 @@ struct _rect *rect_new(double width, double height) } rect->width = width; rect->height = height; + // set parent + rect->shape = shape; - static struct _virtual_table vtb = { - .area = (double (*)(void *self, void *parent))rect_area, - .draw = (void (*)(void *self, void *parent))rect_draw - }; - - rect->shape.vtb = vtb; - // rect->vtb = vtb; return rect; } @@ -147,9 +171,7 @@ struct _circle int invalid; // super - struct _shape shape; - // struct _shape; - // struct _virtual_table vtb; + struct _shape *shape; // attribute double radius; @@ -172,26 +194,35 @@ void circle_draw(struct _circle *self, void *parent) struct _circle *circle_new(double radius) { + // super + static struct _virtual_table vtb = { + .area = (double (*)(void *self, void *parent))circle_area, + .draw = (void (*)(void *self, void *parent))circle_draw, + }; + + struct _shape *shape = shape_new(); + if (shape == NULL) + { + return NULL; + } + shape->vtb = vtb; + + // self struct _circle *circle = calloc(1, sizeof(struct _circle)); if (circle == NULL) { return NULL; } circle->radius = radius; + // set parent + circle->shape = shape; - static struct _virtual_table vtb = { - .area = (double (*)(void *self, void *parent))circle_area, - .draw = (void (*)(void *self, void *parent))circle_draw, - }; - - // circle->vtb = vtb; - circle->shape.vtb = vtb; return circle; } struct _copper_cash { - struct _shape shape; + struct _shape *shape; struct _rect *rect; struct _circle *circle; @@ -200,8 +231,8 @@ struct _copper_cash double copper_cash_area(struct _copper_cash *self, void *parent) { - double circle_area = self->circle->shape.vtb.area(self->circle, self->circle); - double rect_area = self->rect->shape.vtb.area(self->rect, self->rect); + double circle_area = self->circle->shape->vtb.area(self->circle, self->circle); + double rect_area = self->rect->shape->vtb.area(self->rect, self->rect); double area = circle_area - rect_area; printf("copper cash area = %0.2f\n", circle_area - rect_area); @@ -216,32 +247,42 @@ void copper_cash_draw(struct _copper_cash *self, void *parent) struct _copper_cash *copper_cash_new(double width, double height, double radius) { - struct _copper_cash *cc = calloc(1, sizeof(struct _copper_cash)); - if (cc == NULL) + // super + static struct _virtual_table vtb = { + .area = (double (*)(void *self, void *parent))copper_cash_area, + .draw = (void (*)(void *self, void *parent))copper_cash_draw, + }; + + struct _shape *shape = shape_new(); + if (shape == NULL) { return NULL; } + shape->vtb = vtb; struct _rect *rect = rect_new(width, height); if(rect == NULL) { return NULL; } - cc->rect = rect; struct _circle *circle = circle_new(radius); if (circle == NULL) { return NULL; } - cc->circle = circle; - cc->price = 100; - static struct _virtual_table vtb = { - .area = (double (*)(void *self, void *parent))copper_cash_area, - .draw = (void (*)(void *self, void *parent))copper_cash_draw, - }; - cc->shape.vtb = vtb; + // self + struct _copper_cash *cc = calloc(1, sizeof(struct _copper_cash)); + if (cc == NULL) + { + return NULL; + } + cc->price = 100; + // set parent + cc->shape = shape; + cc->rect = rect; + cc->circle = circle; return cc; } @@ -256,20 +297,20 @@ int main(int argc, char *argv[]) circle_draw(circle, circle); printf("----- rect & circle -----\n"); - shape_area(rect, &rect->shape); - shape_draw(rect, &rect->shape); + shape_area(rect, rect->shape); + shape_draw(rect, rect->shape); - shape_area(circle, &circle->shape); - shape_draw(circle, &circle->shape); + shape_area(circle, circle->shape); + shape_draw(circle, circle->shape); printf("----- [2] rect & circle -----\n"); struct _rect *rect2 = (struct _rect *)rect_new(2, 3); - shape_area(rect2, &rect2->shape); - shape_draw(rect2, &rect2->shape); + shape_area(rect2, rect2->shape); + shape_draw(rect2, rect2->shape); struct _circle *circle2 = (struct _circle *)circle_new(1); - shape_area(circle2, &circle->shape); - shape_draw(circle2, &circle->shape); + shape_area(circle2, circle->shape); + shape_draw(circle2, circle->shape); // printf("----- [2] shape -----\n"); // struct _shape *shape = shape_new(); @@ -278,8 +319,11 @@ int main(int argc, char *argv[]) printf("----- copper_cash -----\n"); struct _copper_cash *cc = copper_cash_new(2, 2, 4); - shape_area(cc, &cc->shape); - shape_draw(cc, &cc->shape); + shape_area(cc, cc->shape); + shape_draw(cc, cc->shape); + + printf("----- [2] copper_cash -----\n"); + rect_area(cc, cc->rect); return 0; }