mirror of
https://gitee.com/apaki/cmake_demo.git
synced 2025-07-03 15:56:53 +08:00
多态实现的好奇怪,也勉强能用
This commit is contained in:
parent
5d6d031a3a
commit
d28aec06ca
46
README.md
46
README.md
@ -1,39 +1,15 @@
|
|||||||
# cmake_demo
|
# cmake_demo
|
||||||
|
|
||||||
#### 介绍
|
## CMAKE
|
||||||
{**以下是 Gitee 平台说明,您可以替换此简介**
|
|
||||||
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
|
||||||
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
|
||||||
|
|
||||||
#### 软件架构
|
## 多态
|
||||||
软件架构说明
|
### 多态的本质
|
||||||
|
同样的接口,可以即实现父类的功能,也可以实现子类的功能。主要看传参的类型。
|
||||||
|
|
||||||
|
C语言实现思路:
|
||||||
#### 安装教程
|
因为语法不支持,因此采用特殊的方式来实现。
|
||||||
|
| 类型 | 实现方式 | 弊端| 问题举例|
|
||||||
1. xxxx
|
| --- | --- | --- | --- |
|
||||||
2. xxxx
|
| 匿名结构体 | 指针 | 多重继承,成员可能冲突 | B->A, C->A, D->B,D->C|
|
||||||
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/)
|
|
||||||
|
140
main.c
140
main.c
@ -13,16 +13,16 @@
|
|||||||
|
|
||||||
struct _virtual_table
|
struct _virtual_table
|
||||||
{
|
{
|
||||||
VIRTUAL void (*area)(void *self);
|
VIRTUAL void (*area)(void *self, void *parent);
|
||||||
VIRTUAL void (*draw)(void *self);
|
VIRTUAL void (*draw)(void *self, void *parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
void virtual_area(void *self)
|
void virtual_area(void *self, void *parent)
|
||||||
{
|
{
|
||||||
ASSERT_CALL_VIRTUAL_METHOD();
|
ASSERT_CALL_VIRTUAL_METHOD();
|
||||||
}
|
}
|
||||||
|
|
||||||
void virtual_draw(void *self)
|
void virtual_draw(void *self, void *parent)
|
||||||
{
|
{
|
||||||
ASSERT_CALL_VIRTUAL_METHOD();
|
ASSERT_CALL_VIRTUAL_METHOD();
|
||||||
}
|
}
|
||||||
@ -44,24 +44,24 @@ struct _shape
|
|||||||
struct _virtual_table vtb;
|
struct _virtual_table vtb;
|
||||||
};
|
};
|
||||||
|
|
||||||
void shape_area(void *self)
|
void shape_area(void *self, void *parent)
|
||||||
{
|
{
|
||||||
struct _shape *pthis = (struct _shape *)self;
|
struct _shape *pthis = (struct _shape *)parent;
|
||||||
pthis->vtb.area(self);
|
pthis->vtb.area(self, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shape_draw(void *self)
|
void shape_draw(void *self, void *parent)
|
||||||
{
|
{
|
||||||
struct _shape *pthis = (struct _shape *)self;
|
struct _shape *pthis = (struct _shape *)parent;
|
||||||
pthis->vtb.draw(self);
|
pthis->vtb.draw(self, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE void _shape_area(void *self)
|
PRIVATE void _shape_area(void *self, void *parent)
|
||||||
{
|
{
|
||||||
ASSERT_CALL_VIRTUAL_METHOD();
|
ASSERT_CALL_VIRTUAL_METHOD();
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE void _shape_draw(void *self)
|
PRIVATE void _shape_draw(void *self, void *parent)
|
||||||
{
|
{
|
||||||
ASSERT_CALL_VIRTUAL_METHOD();
|
ASSERT_CALL_VIRTUAL_METHOD();
|
||||||
}
|
}
|
||||||
@ -74,8 +74,8 @@ struct _shape *shape_new(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
static struct _virtual_table vtb = {
|
static struct _virtual_table vtb = {
|
||||||
.area = (void (*)(void *self))_shape_area,
|
.area = (void (*)(void *self, void *parent))_shape_area,
|
||||||
.draw = (void (*)(void *self))_shape_draw
|
.draw = (void (*)(void *self, void *parent))_shape_draw
|
||||||
};
|
};
|
||||||
shape->vtb = vtb;
|
shape->vtb = vtb;
|
||||||
return shape;
|
return shape;
|
||||||
@ -93,9 +93,12 @@ void shape_free(struct _shape * self)
|
|||||||
|
|
||||||
struct _rect
|
struct _rect
|
||||||
{
|
{
|
||||||
|
int invalid;
|
||||||
|
|
||||||
// super
|
// super
|
||||||
// struct _shape shape;
|
struct _shape shape;
|
||||||
struct _virtual_table vtb;
|
// struct _shape;
|
||||||
|
// struct _virtual_table vtb;
|
||||||
|
|
||||||
// attribute
|
// attribute
|
||||||
double width, height;
|
double width, height;
|
||||||
@ -105,12 +108,12 @@ struct _rect
|
|||||||
// void (*draw)(void *self);
|
// 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);
|
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");
|
printf("rect draw\n");
|
||||||
}
|
}
|
||||||
@ -126,19 +129,23 @@ struct _rect *rect_new(double width, double height)
|
|||||||
rect->height = height;
|
rect->height = height;
|
||||||
|
|
||||||
static struct _virtual_table vtb = {
|
static struct _virtual_table vtb = {
|
||||||
.area = (void (*)(void *self))rect_area,
|
.area = (void (*)(void *self, void *parent))rect_area,
|
||||||
.draw = (void (*)(void *self))rect_draw
|
.draw = (void (*)(void *self, void *parent))rect_draw
|
||||||
};
|
};
|
||||||
|
|
||||||
rect->vtb = vtb;
|
rect->shape.vtb = vtb;
|
||||||
|
// rect->vtb = vtb;
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _circle
|
struct _circle
|
||||||
{
|
{
|
||||||
|
int invalid;
|
||||||
|
|
||||||
// super
|
// super
|
||||||
// struct _shape shape;
|
struct _shape shape;
|
||||||
struct _virtual_table vtb;
|
// struct _shape;
|
||||||
|
// struct _virtual_table vtb;
|
||||||
|
|
||||||
// attribute
|
// attribute
|
||||||
double radius;
|
double radius;
|
||||||
@ -148,11 +155,11 @@ struct _circle
|
|||||||
// void (*draw)(void *self);
|
// 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);
|
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");
|
printf("circle draw\n");
|
||||||
}
|
}
|
||||||
@ -167,46 +174,85 @@ struct _circle *circle_new(double radius)
|
|||||||
circle->radius = radius;
|
circle->radius = radius;
|
||||||
|
|
||||||
static struct _virtual_table vtb = {
|
static struct _virtual_table vtb = {
|
||||||
.area = (void (*)(void *self))circle_area,
|
.area = (void (*)(void *self, void *parent))circle_area,
|
||||||
.draw = (void (*)(void *self))circle_draw,
|
.draw = (void (*)(void *self, void *parent))circle_draw,
|
||||||
};
|
};
|
||||||
|
|
||||||
circle->vtb = vtb;
|
// circle->vtb = vtb;
|
||||||
|
circle->shape.vtb = vtb;
|
||||||
return circle;
|
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[])
|
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);
|
||||||
rect_draw(rect);
|
rect_draw(rect, rect);
|
||||||
|
|
||||||
struct _circle *circle = circle_new(3);
|
struct _circle *circle = circle_new(3);
|
||||||
circle_area(circle);
|
circle_area(circle, circle);
|
||||||
circle_draw(circle);
|
circle_draw(circle, circle);
|
||||||
|
|
||||||
printf("------------------------------\n");
|
printf("------------------------------\n");
|
||||||
shape_area(rect);
|
shape_area(rect, &rect->shape);
|
||||||
shape_area(circle);
|
shape_draw(rect, &rect->shape);
|
||||||
|
|
||||||
shape_draw(rect);
|
shape_area(circle, &circle->shape);
|
||||||
shape_draw(circle);
|
shape_draw(circle, &circle->shape);
|
||||||
|
|
||||||
printf("------------------------------\n");
|
printf("------------------------------\n");
|
||||||
struct _shape *shape = (struct _shape *)rect_new(2,3);
|
struct _rect *rect2 = (struct _rect *)rect_new(2, 3);
|
||||||
shape_area(shape);
|
shape_area(rect2, &rect2->shape);
|
||||||
shape_draw(shape);
|
shape_draw(rect2, &rect2->shape);
|
||||||
|
|
||||||
struct _shape *shape2 = NULL;
|
|
||||||
shape2 = (struct _shape *)circle;
|
|
||||||
shape_area(shape2);
|
|
||||||
shape_draw(shape2);
|
|
||||||
|
|
||||||
|
struct _circle *circle2 = (struct _circle *)circle_new(1);
|
||||||
|
shape_area(circle2, &circle->shape);
|
||||||
|
shape_draw(circle2, &circle->shape);
|
||||||
|
|
||||||
printf("------------------------------\n");
|
printf("------------------------------\n");
|
||||||
struct _shape *shape3 = shape_new();
|
struct _shape *shape = shape_new();
|
||||||
shape_area(shape3);
|
shape_area(shape, shape);
|
||||||
shape_draw(shape3);
|
shape_draw(shape, shape);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user