diff --git a/README.md b/README.md index ff07f81..22dfc7d 100644 --- a/README.md +++ b/README.md @@ -1,39 +1,15 @@ # cmake_demo -#### 介绍 -{**以下是 Gitee 平台说明,您可以替换此简介** -Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} +## CMAKE -#### 软件架构 -软件架构说明 +## 多态 +### 多态的本质 +同样的接口,可以即实现父类的功能,也可以实现子类的功能。主要看传参的类型。 - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +C语言实现思路: +因为语法不支持,因此采用特殊的方式来实现。 +| 类型 | 实现方式 | 弊端| 问题举例| +| --- | --- | --- | --- | +| 匿名结构体 | 指针 | 多重继承,成员可能冲突 | B->A, C->A, D->B,D->C| +| 虚函数表 | 指针 | 子类父类必须将虚表放在结构体最开头,且不支持多继承下的多态 | | +| 虚函数多参数 | 指针 | 继承的父类无顺序强制要求,且可以多继承。但类方法参数变多 | | diff --git a/main.c b/main.c index 6c15aab..71d81af 100644 --- a/main.c +++ b/main.c @@ -13,16 +13,16 @@ struct _virtual_table { - VIRTUAL void (*area)(void *self); - VIRTUAL void (*draw)(void *self); + VIRTUAL void (*area)(void *self, void *parent); + VIRTUAL void (*draw)(void *self, void *parent); }; -void virtual_area(void *self) +void virtual_area(void *self, void *parent) { ASSERT_CALL_VIRTUAL_METHOD(); } -void virtual_draw(void *self) +void virtual_draw(void *self, void *parent) { ASSERT_CALL_VIRTUAL_METHOD(); } @@ -44,24 +44,24 @@ struct _shape struct _virtual_table vtb; }; -void shape_area(void *self) +void shape_area(void *self, void *parent) { - struct _shape *pthis = (struct _shape *)self; - pthis->vtb.area(self); + struct _shape *pthis = (struct _shape *)parent; + pthis->vtb.area(self, NULL); } -void shape_draw(void *self) +void shape_draw(void *self, void *parent) { - struct _shape *pthis = (struct _shape *)self; - pthis->vtb.draw(self); + struct _shape *pthis = (struct _shape *)parent; + pthis->vtb.draw(self, NULL); } -PRIVATE void _shape_area(void *self) +PRIVATE void _shape_area(void *self, void *parent) { ASSERT_CALL_VIRTUAL_METHOD(); } -PRIVATE void _shape_draw(void *self) +PRIVATE void _shape_draw(void *self, void *parent) { ASSERT_CALL_VIRTUAL_METHOD(); } @@ -74,8 +74,8 @@ struct _shape *shape_new(void) return NULL; } static struct _virtual_table vtb = { - .area = (void (*)(void *self))_shape_area, - .draw = (void (*)(void *self))_shape_draw + .area = (void (*)(void *self, void *parent))_shape_area, + .draw = (void (*)(void *self, void *parent))_shape_draw }; shape->vtb = vtb; return shape; @@ -93,9 +93,12 @@ void shape_free(struct _shape * self) struct _rect { + int invalid; + // super - // struct _shape shape; - struct _virtual_table vtb; + struct _shape shape; + // struct _shape; + // struct _virtual_table vtb; // attribute double width, height; @@ -105,12 +108,12 @@ struct _rect // void (*draw)(void *self); }; -void rect_area(struct _rect *self) +void rect_area(struct _rect *self, void *parent) { printf("rect area = %0.2f\n", self->width * self->height); } -void rect_draw(struct _rect *self) +void rect_draw(struct _rect *self, void *parent) { printf("rect draw\n"); } @@ -126,19 +129,23 @@ struct _rect *rect_new(double width, double height) rect->height = height; static struct _virtual_table vtb = { - .area = (void (*)(void *self))rect_area, - .draw = (void (*)(void *self))rect_draw + .area = (void (*)(void *self, void *parent))rect_area, + .draw = (void (*)(void *self, void *parent))rect_draw }; - rect->vtb = vtb; + rect->shape.vtb = vtb; + // rect->vtb = vtb; return rect; } struct _circle { + int invalid; + // super - // struct _shape shape; - struct _virtual_table vtb; + struct _shape shape; + // struct _shape; + // struct _virtual_table vtb; // attribute double radius; @@ -148,11 +155,11 @@ struct _circle // void (*draw)(void *self); }; -void circle_area(struct _circle *self) +void circle_area(struct _circle *self, void *parent) { printf("circle area = %0.2f\n", 3.14 * self->radius * self->radius); } -void circle_draw(struct _circle *self) +void circle_draw(struct _circle *self, void *parent) { printf("circle draw\n"); } @@ -167,46 +174,85 @@ struct _circle *circle_new(double radius) circle->radius = radius; static struct _virtual_table vtb = { - .area = (void (*)(void *self))circle_area, - .draw = (void (*)(void *self))circle_draw, + .area = (void (*)(void *self, void *parent))circle_area, + .draw = (void (*)(void *self, void *parent))circle_draw, }; - circle->vtb = vtb; + // circle->vtb = vtb; + circle->shape.vtb = vtb; return circle; } +#if 0 +struct _cube +{ + // 继承自 struct _shape + struct _rect; + + // attibute + double length; +}; + +void cube_area(struct _cube *self) +{ + printf("cube area = %0.2f\n", self->length * self->length * self->length); +} + +void cube_draw(struct _cube *self) +{ + printf("cube draw\n"); +} + +struct _cube* cube_new(double length) +{ + struct _cube *cube = calloc(1, sizeof(struct _cube)); + if (cube == NULL) + { + return NULL; + } + cube->length = length; + + static struct _virtual_table vtb = { + .area = (void (*)(void *self))cube_area, + .draw = (void (*)(void *self))cube_draw, + }; + + cube->vtb = vtb; + return cube; +} +#endif + + int main(int argc, char *argv[]) { struct _rect *rect = rect_new(4, 5); - rect_area(rect); - rect_draw(rect); + rect_area(rect, rect); + rect_draw(rect, rect); struct _circle *circle = circle_new(3); - circle_area(circle); - circle_draw(circle); + circle_area(circle, circle); + circle_draw(circle, circle); printf("------------------------------\n"); - shape_area(rect); - shape_area(circle); + shape_area(rect, &rect->shape); + shape_draw(rect, &rect->shape); - shape_draw(rect); - shape_draw(circle); + shape_area(circle, &circle->shape); + shape_draw(circle, &circle->shape); printf("------------------------------\n"); - struct _shape *shape = (struct _shape *)rect_new(2,3); - shape_area(shape); - shape_draw(shape); - - struct _shape *shape2 = NULL; - shape2 = (struct _shape *)circle; - shape_area(shape2); - shape_draw(shape2); + struct _rect *rect2 = (struct _rect *)rect_new(2, 3); + 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); printf("------------------------------\n"); - struct _shape *shape3 = shape_new(); - shape_area(shape3); - shape_draw(shape3); + struct _shape *shape = shape_new(); + shape_area(shape, shape); + shape_draw(shape, shape); return 0; }