diff --git a/CMakelists.txt b/CMakelists.txt index 447149c..f80f03d 100644 --- a/CMakelists.txt +++ b/CMakelists.txt @@ -50,10 +50,10 @@ install(TARGETS demo DESTINATION bin) install (FILES "${PROJECT_BINARY_DIR}/config.h" DESTINATION include) -# 4. 启用测试 -enable_testing() -# 测试程序是否成功运行 -add_test (NAME test_demo COMMAND demo 1 2 3 5 8) +# # 4. 启用测试 +# enable_testing() +# # 测试程序是否成功运行 +# add_test (NAME test_demo COMMAND demo 1 2 3 5 8) # 5. 支持GDB set(CMAKE_BUILD_TYPE "Debug") diff --git a/main.c b/main.c index 6e4ddac..c99c985 100644 --- a/main.c +++ b/main.c @@ -3,28 +3,66 @@ #include #include #include +#include + +#define VIRTUAL +#define PRIVATE + +struct _virtual_table +{ + VIRTUAL void (*area)(void *self); + VIRTUAL void (*draw)(void *self); +}; + +void virtual_area(void *self) +{ + assert(!"can't call abstract method"); +} + +void virtual_draw(void *self) +{ + assert(!"can't call abstract method"); +} + +struct _virtual_table *virtual_new(void) +{ + struct _virtual_table *v = calloc(1, sizeof(struct _virtual_table)); + if (v == NULL) + { + return NULL; + } + v->area = virtual_area; + v->draw = virtual_draw; + return v; +} + -#define VIRTUAL struct _shape { - VIRTUAL void (*area)(struct _shape *self); - VIRTUAL void (*draw)(struct _shape *self); + VIRTUAL void (*area)(void *self); + VIRTUAL void (*draw)(void *self); }; -void shape_area(struct _shape *self) +void shape_area(void *self) { - printf("shape area\n"); + assert(!"can't call abstract method"); } -void shape_draw(struct _shape *self) +void shape_draw(void *self) { - printf("shape draw\n"); + assert(!"can't call abstract method"); } struct _shape *shape_new(void) { struct _shape *shape = calloc(1, sizeof(struct _shape)); + if(shape == NULL) + { + return NULL; + } + shape->area = shape_area; + shape->draw = shape_draw; return shape; } @@ -38,17 +76,19 @@ void shape_free(struct _shape * self) } #endif +#define SUPER(self) ((self)->shape) + struct _rect { // super - // struct _shape shape; + struct _shape* shape; // attribute double width, height; // method - void (*area)(struct _rect *self); - void (*draw)(struct _rect *self); + // void (*area)(void *self); + // void (*draw)(void *self); }; void rect_area(struct _rect *self) @@ -71,22 +111,28 @@ struct _rect *rect_new(double width, double height) rect->width = width; rect->height = height; - rect->area = rect_area; - rect->draw = rect_draw; + rect->shape = shape_new(); + if (rect->shape == NULL) + { + return NULL; + } + + SUPER(rect)->area = (void (*)(void *self))rect_area; + SUPER(rect)->draw = (void (*)(void *self))rect_draw; return rect; } struct _circle { // super - // struct _shape shape; + struct _shape *shape; // attribute double radius; // method - void (*area)(struct _circle *self); - void (*draw)(struct _circle *self); + // void (*area)(void *self); + // void (*draw)(void *self); }; void circle_area(struct _circle *self) @@ -105,22 +151,38 @@ struct _circle *circle_new(double radius) { return NULL; } + circle->shape = shape_new(); + if (circle->shape == NULL) + { + return NULL; + } + circle->radius = radius; - circle->area = circle_area; - circle->draw = circle_draw; + SUPER(circle)->area = (void (*)(void *self))circle_area; + SUPER(circle)->draw = (void (*)(void *self))circle_draw; return circle; } int main(int argc, char *argv[]) { struct _rect *rect = rect_new(4, 5); - rect->area(rect); - rect->draw(rect); + rect_area(rect); + rect_draw(rect); struct _circle *circle = circle_new(3); - circle->area(circle); - circle->draw(circle); + circle_area(circle); + circle_draw(circle); + + // struct shape *shape = shape_new(); + // shape_area(shape); + // shape_draw(shape); + + // struct _shape *shape = NULL; + struct _shape *shape = rect_new(2,3); + // shape = rect; + shape_area(shape); + shape_draw(shape); return 0; } diff --git a/mk.bat b/mk.bat index aedfdac..06c2b32 100644 --- a/mk.bat +++ b/mk.bat @@ -1,6 +1,8 @@ @REM D:\Lang\cmake-3.27.5-windows-x86_64\bin\cmake.EXE --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_C_COMPILER:FILEPATH=D:\Software\mingw64\bin\gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=D:\Software\mingw64\bin\g++.exe -SF:/OpenDemo/1_vsc_cmake -Bf:/OpenDemo/1_vsc_cmake/build -G "MinGW Makefiles" @REM cmake -Bbuild -G "Visual Studio 17 2022" +del ".\\build\\release\\bin\\demo.exe" + cmake -B build -G "MinGW Makefiles" make -C build @@ -10,4 +12,4 @@ make -C build test @REM cpack -C ./build/CPackConfig.cmake @REM cpack -C ./build/CPackSourceConfig.cmake -"build/release/bin/demo.exe" +".\\build\\release\\bin\\demo.exe"