diff --git a/CMakelists.txt b/CMakelists.txt index dfd6194..901ffd6 100644 --- a/CMakelists.txt +++ b/CMakelists.txt @@ -8,5 +8,7 @@ set(CMAKE_BUILD_TYPE "Debug") set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb") set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall") +include_directories(library) + add_subdirectory(library) add_subdirectory(src) diff --git a/library/circle.c b/library/circle.c new file mode 100644 index 0000000..c4e4a62 --- /dev/null +++ b/library/circle.c @@ -0,0 +1,57 @@ + +#include "circle.h" + +double circle_area(void *self, void *parent) +{ + double area = 0; + struct _circle *pthis = (struct _circle *)parent; + area = pthis->shape->vtb.area(self, NULL); + return area; +} + +void circle_draw(void *self, void *parent) +{ + struct _circle *pthis = (struct _circle *)parent; + pthis->shape->vtb.draw(self, NULL); +} + +double _circle_area(void *self, void *parent) +{ + struct _circle *pthis = (struct _circle *)self; + double area = 3.14 * pthis->radius * pthis->radius; + printf("circle area = %0.2f\n", area); + return area; +} + +void _circle_draw(void *self, void *parent) +{ + printf("circle draw\n"); +} + +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; + + return circle; +} diff --git a/library/circle.h b/library/circle.h new file mode 100644 index 0000000..263e059 --- /dev/null +++ b/library/circle.h @@ -0,0 +1,28 @@ + +#ifndef _CIRCLE_H_ +#define _CIRCLE_H_ + +#include "common.h" +#include "shape.h" + +struct _circle +{ + int invalid; + + // super + struct _shape *shape; + + // attribute + double radius; + + // method + // void (*area)(void *self); + // void (*draw)(void *self); +}; + +struct _circle *circle_new(double radius); + +double circle_area(void *self, void *parent); +void circle_draw(void *self, void *parent); + +#endif diff --git a/library/common.h b/library/common.h new file mode 100644 index 0000000..f64363a --- /dev/null +++ b/library/common.h @@ -0,0 +1,11 @@ + +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include +#include +#include +#include +#include + +#endif diff --git a/library/copper.c b/library/copper.c new file mode 100644 index 0000000..0b1a3f8 --- /dev/null +++ b/library/copper.c @@ -0,0 +1,67 @@ + +#include "copper.h" + +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 = 3.14 * self->circle->radius * self->circle->radius; + double rect_area = self->rect->width * self->rect->height; + double area = circle_area - rect_area; + + printf("copper cash area = %0.2f\n", circle_area - rect_area); + return area; +} + +void copper_cash_draw(struct _copper_cash *self, void *parent) +{ + printf("copper cash draw\n"); +} + + +struct _copper_cash *copper_cash_new(double width, double height, double radius) +{ + // 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; + } + rect->shape = shape; + + struct _circle *circle = circle_new(radius); + if (circle == NULL) + { + return NULL; + } + circle->shape = shape; + + // 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; +} diff --git a/library/copper.h b/library/copper.h new file mode 100644 index 0000000..4f5a20a --- /dev/null +++ b/library/copper.h @@ -0,0 +1,24 @@ + +#ifndef _COPPER_CASH_H_ +#define _COPPER_CASH_H_ + +#include "common.h" +#include "shape.h" +#include "rect.h" +#include "circle.h" + +struct _copper_cash +{ + struct _shape *shape; + struct _rect *rect; + struct _circle *circle; + + double price; +}; + +struct _copper_cash *copper_cash_new(double width, double height, double radius); + +double copper_cash_area(struct _copper_cash *self, void *parent); +void copper_cash_draw(struct _copper_cash *self, void *parent); + +#endif diff --git a/library/list.c b/library/list.c deleted file mode 100644 index ee6d6cc..0000000 --- a/library/list.c +++ /dev/null @@ -1,58 +0,0 @@ - -#include "list.h" - -void list_init(struct list_t *list) -{ - list->data = 0; - list->next = NULL; -} - -void list_add(struct list_t *list, uint8_t data) -{ - struct list_t *p = NULL; - p = list; - while (p->next != NULL) - { - p = p->next; - if (p->data == data) - { - return; - } - } - p->next = (struct list_t *)malloc(sizeof(struct list_t)); - p->next->data = data; - p->next->next = NULL; - return; -} - -void list_print(struct list_t *list) -{ - struct list_t *p = NULL; - p = list; - while (p->next != NULL) - { - printf("%02d ", p->data); - p = p->next; - if (p->next == NULL) - { - printf("%02d\n", p->data); - break; - } - } -} - -void list_free(struct list_t *list) -{ - struct list_t *p = NULL; - p = list; - while (p->next != NULL) - { - p = p->next; - free(p->next); - p->next = NULL; - if (p->next == NULL) - { - break; - } - } -} diff --git a/library/list.h b/library/list.h deleted file mode 100644 index 82f925c..0000000 --- a/library/list.h +++ /dev/null @@ -1,20 +0,0 @@ - -#ifndef _LIST_H_ -#define _LIST_H_ - -#include -#include -#include - -typedef struct list_t -{ - uint8_t data; - struct list_t *next; -} list_t; - -void list_init(struct list_t *list); -void list_add(struct list_t *list, uint8_t data); -void list_print(struct list_t *list); -void list_free(struct list_t *list); - -#endif diff --git a/library/rect.c b/library/rect.c new file mode 100644 index 0000000..a70eebf --- /dev/null +++ b/library/rect.c @@ -0,0 +1,59 @@ + +#include "rect.h" + +double rect_area(void *self, void *parent) +{ + 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) +{ + struct _rect *pthis = (struct _rect *)parent; + pthis->shape->vtb.draw(self, NULL); +} + +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(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) + { + return NULL; + } + rect->width = width; + rect->height = height; + // set parent + rect->shape = shape; + + return rect; +} diff --git a/library/rect.h b/library/rect.h new file mode 100644 index 0000000..18c8bf9 --- /dev/null +++ b/library/rect.h @@ -0,0 +1,24 @@ + +#ifndef _RECT_H_ +#define _RECT_H_ + +#include "common.h" +#include "shape.h" + +struct _rect +{ + int invalid; + + // super + struct _shape *shape; + + // attribute + double width, height; +}; + +struct _rect *rect_new(double width, double height); + +double rect_area(void *self, void *parent); +void rect_draw(void *self, void *parent); + +#endif diff --git a/library/shape.c b/library/shape.c new file mode 100644 index 0000000..7d8037a --- /dev/null +++ b/library/shape.c @@ -0,0 +1,75 @@ + +#include "shape.h" + +double virtual_area(void *self, void *parent) +{ + ASSERT_CALL_VIRTUAL_METHOD(); +} + +void virtual_draw(void *self, void *parent) +{ + 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; +} + + + +double shape_area(void *self, void *parent) +{ + double area = 0; + struct _shape *pthis = (struct _shape *)parent; + area = pthis->vtb.area(self, NULL); + return area; +} + +void shape_draw(void *self, void *parent) +{ + struct _shape *pthis = (struct _shape *)parent; + pthis->vtb.draw(self, NULL); +} + +PRIVATE double _shape_area(void *self, void *parent) +{ + ASSERT_CALL_VIRTUAL_METHOD(); +} + +PRIVATE void _shape_draw(void *self, void *parent) +{ + ASSERT_CALL_VIRTUAL_METHOD(); +} + +struct _shape *shape_new(void) +{ + struct _shape *shape = calloc(1, sizeof(struct _shape)); + if(shape == NULL) + { + return NULL; + } + static struct _virtual_table vtb = { + .area = (double (*)(void *self, void *parent))_shape_area, + .draw = (void (*)(void *self, void *parent))_shape_draw + }; + shape->vtb = vtb; + return shape; +} + +#if 0 +void shape_free(struct _shape * self) +{ + if (self != NULL) + { + free(self); + } +} +#endif diff --git a/library/shape.h b/library/shape.h new file mode 100644 index 0000000..aef632e --- /dev/null +++ b/library/shape.h @@ -0,0 +1,30 @@ + +#ifndef _SHAPE_H_ +#define _SHAPE_H_ + +#include "common.h" + +#define VIRTUAL +#define PRIVATE static + +#define ASSERT_CALL_VIRTUAL_METHOD() assert(!("can't call abstract method")) + +struct _virtual_table +{ + VIRTUAL double (*area)(void *self, void *parent); + VIRTUAL void (*draw)(void *self, void *parent); +}; + +struct _shape +{ + struct _virtual_table vtb; +}; + + +struct _shape *shape_new(void); + +double shape_area(void *self, void *parent); +void shape_draw(void *self, void *parent); + +#endif + diff --git a/src/main.c b/src/main.c index 6e224e8..5970521 100644 --- a/src/main.c +++ b/src/main.c @@ -1,313 +1,8 @@ -#include -#include -#include -#include -#include - -#define VIRTUAL -#define PRIVATE static - -#define ASSERT_CALL_VIRTUAL_METHOD() assert(!("can't call abstract method")) - - -struct _virtual_table -{ - VIRTUAL double (*area)(void *self, void *parent); - VIRTUAL void (*draw)(void *self, void *parent); -}; - -double virtual_area(void *self, void *parent) -{ - ASSERT_CALL_VIRTUAL_METHOD(); -} - -void virtual_draw(void *self, void *parent) -{ - 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; -} - -struct _shape -{ - struct _virtual_table vtb; -}; - -double shape_area(void *self, void *parent) -{ - double area = 0; - struct _shape *pthis = (struct _shape *)parent; - area = pthis->vtb.area(self, NULL); - return area; -} - -void shape_draw(void *self, void *parent) -{ - struct _shape *pthis = (struct _shape *)parent; - pthis->vtb.draw(self, NULL); -} - -PRIVATE double _shape_area(void *self, void *parent) -{ - ASSERT_CALL_VIRTUAL_METHOD(); -} - -PRIVATE void _shape_draw(void *self, void *parent) -{ - ASSERT_CALL_VIRTUAL_METHOD(); -} - -struct _shape *shape_new(void) -{ - struct _shape *shape = calloc(1, sizeof(struct _shape)); - if(shape == NULL) - { - return NULL; - } - static struct _virtual_table vtb = { - .area = (double (*)(void *self, void *parent))_shape_area, - .draw = (void (*)(void *self, void *parent))_shape_draw - }; - shape->vtb = vtb; - return shape; -} - -#if 0 -void shape_free(struct _shape * self) -{ - if (self != NULL) - { - free(self); - } -} -#endif - -struct _rect -{ - int invalid; - - // super - struct _shape *shape; - // struct _shape; - // struct _virtual_table vtb; - - // attribute - double width, height; - - // method - // void (*area)(void *self); - // void (*draw)(void *self); -}; - -double rect_area(void *self, void *parent) -{ - 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) -{ - struct _rect *pthis = (struct _rect *)parent; - pthis->shape->vtb.draw(self, NULL); -} - -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(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) - { - return NULL; - } - rect->width = width; - rect->height = height; - // set parent - rect->shape = shape; - - return rect; -} - -struct _circle -{ - int invalid; - - // super - struct _shape *shape; - - // attribute - double radius; - - // method - // void (*area)(void *self); - // void (*draw)(void *self); -}; - -double circle_area(void *self, void *parent) -{ - double area = 0; - struct _circle *pthis = (struct _circle *)parent; - area = pthis->shape->vtb.area(self, NULL); - return area; -} -void circle_draw(void *self, void *parent) -{ - struct _circle *pthis = (struct _circle *)parent; - pthis->shape->vtb.draw(self, NULL); -} - -double _circle_area(void *self, void *parent) -{ - struct _circle *pthis = (struct _circle *)self; - double area = 3.14 * pthis->radius * pthis->radius; - printf("circle area = %0.2f\n", area); - return area; -} -void _circle_draw(void *self, void *parent) -{ - printf("circle draw\n"); -} - -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; - - return circle; -} - -struct _copper_cash -{ - struct _shape *shape; - struct _rect *rect; - struct _circle *circle; - - double price; -}; - -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 = 3.14 * self->circle->radius * self->circle->radius; - double rect_area = self->rect->width * self->rect->height; - double area = circle_area - rect_area; - - printf("copper cash area = %0.2f\n", circle_area - rect_area); - return area; -} - -void copper_cash_draw(struct _copper_cash *self, void *parent) -{ - printf("copper cash draw\n"); -} - - -struct _copper_cash *copper_cash_new(double width, double height, double radius) -{ - // 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; - } - rect->shape = shape; - - struct _circle *circle = circle_new(radius); - if (circle == NULL) - { - return NULL; - } - circle->shape = shape; - - // 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; -} +#include "shape.h" +#include "rect.h" +#include "circle.h" +#include "copper.h" int main(int argc, char *argv[]) {