mirror of
https://gitee.com/apaki/cmake_demo.git
synced 2025-05-17 20:01:36 +08:00
如果只是这样实现,那么无法多态。即给父类赋值子类,然后调用父类,实测还是调用的父类接口。因此添加虚函数表
This commit is contained in:
parent
196c331520
commit
7021105e64
@ -50,10 +50,10 @@ install(TARGETS demo DESTINATION bin)
|
|||||||
install (FILES "${PROJECT_BINARY_DIR}/config.h"
|
install (FILES "${PROJECT_BINARY_DIR}/config.h"
|
||||||
DESTINATION include)
|
DESTINATION include)
|
||||||
|
|
||||||
# 4. 启用测试
|
# # 4. 启用测试
|
||||||
enable_testing()
|
# enable_testing()
|
||||||
# 测试程序是否成功运行
|
# # 测试程序是否成功运行
|
||||||
add_test (NAME test_demo COMMAND demo 1 2 3 5 8)
|
# add_test (NAME test_demo COMMAND demo 1 2 3 5 8)
|
||||||
|
|
||||||
# 5. 支持GDB
|
# 5. 支持GDB
|
||||||
set(CMAKE_BUILD_TYPE "Debug")
|
set(CMAKE_BUILD_TYPE "Debug")
|
||||||
|
102
main.c
102
main.c
@ -3,28 +3,66 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#define VIRTUAL
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct _shape
|
struct _shape
|
||||||
{
|
{
|
||||||
VIRTUAL void (*area)(struct _shape *self);
|
VIRTUAL void (*area)(void *self);
|
||||||
VIRTUAL void (*draw)(struct _shape *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_new(void)
|
||||||
{
|
{
|
||||||
struct _shape *shape = calloc(1, sizeof(struct _shape));
|
struct _shape *shape = calloc(1, sizeof(struct _shape));
|
||||||
|
if(shape == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
shape->area = shape_area;
|
||||||
|
shape->draw = shape_draw;
|
||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,17 +76,19 @@ void shape_free(struct _shape * self)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define SUPER(self) ((self)->shape)
|
||||||
|
|
||||||
struct _rect
|
struct _rect
|
||||||
{
|
{
|
||||||
// super
|
// super
|
||||||
// struct _shape shape;
|
struct _shape* shape;
|
||||||
|
|
||||||
// attribute
|
// attribute
|
||||||
double width, height;
|
double width, height;
|
||||||
|
|
||||||
// method
|
// method
|
||||||
void (*area)(struct _rect *self);
|
// void (*area)(void *self);
|
||||||
void (*draw)(struct _rect *self);
|
// void (*draw)(void *self);
|
||||||
};
|
};
|
||||||
|
|
||||||
void rect_area(struct _rect *self)
|
void rect_area(struct _rect *self)
|
||||||
@ -71,22 +111,28 @@ struct _rect *rect_new(double width, double height)
|
|||||||
rect->width = width;
|
rect->width = width;
|
||||||
rect->height = height;
|
rect->height = height;
|
||||||
|
|
||||||
rect->area = rect_area;
|
rect->shape = shape_new();
|
||||||
rect->draw = rect_draw;
|
if (rect->shape == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SUPER(rect)->area = (void (*)(void *self))rect_area;
|
||||||
|
SUPER(rect)->draw = (void (*)(void *self))rect_draw;
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _circle
|
struct _circle
|
||||||
{
|
{
|
||||||
// super
|
// super
|
||||||
// struct _shape shape;
|
struct _shape *shape;
|
||||||
|
|
||||||
// attribute
|
// attribute
|
||||||
double radius;
|
double radius;
|
||||||
|
|
||||||
// method
|
// method
|
||||||
void (*area)(struct _circle *self);
|
// void (*area)(void *self);
|
||||||
void (*draw)(struct _circle *self);
|
// void (*draw)(void *self);
|
||||||
};
|
};
|
||||||
|
|
||||||
void circle_area(struct _circle *self)
|
void circle_area(struct _circle *self)
|
||||||
@ -105,22 +151,38 @@ struct _circle *circle_new(double radius)
|
|||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
circle->shape = shape_new();
|
||||||
|
if (circle->shape == NULL)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
circle->radius = radius;
|
circle->radius = radius;
|
||||||
|
|
||||||
circle->area = circle_area;
|
SUPER(circle)->area = (void (*)(void *self))circle_area;
|
||||||
circle->draw = circle_draw;
|
SUPER(circle)->draw = (void (*)(void *self))circle_draw;
|
||||||
return circle;
|
return circle;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct _rect *rect = rect_new(4, 5);
|
struct _rect *rect = rect_new(4, 5);
|
||||||
rect->area(rect);
|
rect_area(rect);
|
||||||
rect->draw(rect);
|
rect_draw(rect);
|
||||||
|
|
||||||
struct _circle *circle = circle_new(3);
|
struct _circle *circle = circle_new(3);
|
||||||
circle->area(circle);
|
circle_area(circle);
|
||||||
circle->draw(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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
4
mk.bat
4
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 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"
|
@REM cmake -Bbuild -G "Visual Studio 17 2022"
|
||||||
|
|
||||||
|
del ".\\build\\release\\bin\\demo.exe"
|
||||||
|
|
||||||
cmake -B build -G "MinGW Makefiles"
|
cmake -B build -G "MinGW Makefiles"
|
||||||
|
|
||||||
make -C build
|
make -C build
|
||||||
@ -10,4 +12,4 @@ make -C build test
|
|||||||
@REM cpack -C ./build/CPackConfig.cmake
|
@REM cpack -C ./build/CPackConfig.cmake
|
||||||
@REM cpack -C ./build/CPackSourceConfig.cmake
|
@REM cpack -C ./build/CPackSourceConfig.cmake
|
||||||
|
|
||||||
"build/release/bin/demo.exe"
|
".\\build\\release\\bin\\demo.exe"
|
||||||
|
Loading…
Reference in New Issue
Block a user