shape也修改成指针,但最后一句代码还存在问题

This commit is contained in:
建峰 2024-09-01 16:28:49 +08:00
parent 5975890154
commit fd35e92c42

132
main.c
View File

@ -98,7 +98,7 @@ struct _rect
int invalid; int invalid;
// super // super
struct _shape shape; struct _shape *shape;
// struct _shape; // struct _shape;
// struct _virtual_table vtb; // struct _virtual_table vtb;
@ -110,20 +110,49 @@ struct _rect
// void (*draw)(void *self); // void (*draw)(void *self);
}; };
double rect_area(struct _rect *self, void *parent) double rect_area(void *self, void *parent)
{ {
double area = self->width * self->height; 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)
{
printf("rect draw\n");
}
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); printf("rect area = %0.2f\n", area);
return area; return area;
} }
void rect_draw(struct _rect *self, void *parent) void _rect_draw(void *self, void *parent)
{ {
printf("rect draw\n"); printf("rect draw\n");
} }
struct _rect *rect_new(double width, double height) 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)); struct _rect *rect = calloc(1, sizeof(struct _rect));
if (rect == NULL) if (rect == NULL)
{ {
@ -131,14 +160,9 @@ struct _rect *rect_new(double width, double height)
} }
rect->width = width; rect->width = width;
rect->height = height; rect->height = height;
// set parent
rect->shape = shape;
static struct _virtual_table vtb = {
.area = (double (*)(void *self, void *parent))rect_area,
.draw = (void (*)(void *self, void *parent))rect_draw
};
rect->shape.vtb = vtb;
// rect->vtb = vtb;
return rect; return rect;
} }
@ -147,9 +171,7 @@ struct _circle
int invalid; int invalid;
// super // super
struct _shape shape; struct _shape *shape;
// struct _shape;
// struct _virtual_table vtb;
// attribute // attribute
double radius; double radius;
@ -172,26 +194,35 @@ void circle_draw(struct _circle *self, void *parent)
struct _circle *circle_new(double radius) 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)); struct _circle *circle = calloc(1, sizeof(struct _circle));
if (circle == NULL) if (circle == NULL)
{ {
return NULL; return NULL;
} }
circle->radius = radius; circle->radius = radius;
// set parent
circle->shape = shape;
static struct _virtual_table vtb = {
.area = (double (*)(void *self, void *parent))circle_area,
.draw = (void (*)(void *self, void *parent))circle_draw,
};
// circle->vtb = vtb;
circle->shape.vtb = vtb;
return circle; return circle;
} }
struct _copper_cash struct _copper_cash
{ {
struct _shape shape; struct _shape *shape;
struct _rect *rect; struct _rect *rect;
struct _circle *circle; struct _circle *circle;
@ -200,8 +231,8 @@ struct _copper_cash
double copper_cash_area(struct _copper_cash *self, void *parent) double copper_cash_area(struct _copper_cash *self, void *parent)
{ {
double circle_area = self->circle->shape.vtb.area(self->circle, self->circle); 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 rect_area = self->rect->shape->vtb.area(self->rect, self->rect);
double area = circle_area - rect_area; double area = circle_area - rect_area;
printf("copper cash area = %0.2f\n", circle_area - rect_area); printf("copper cash area = %0.2f\n", circle_area - rect_area);
@ -216,32 +247,42 @@ void copper_cash_draw(struct _copper_cash *self, void *parent)
struct _copper_cash *copper_cash_new(double width, double height, double radius) struct _copper_cash *copper_cash_new(double width, double height, double radius)
{ {
struct _copper_cash *cc = calloc(1, sizeof(struct _copper_cash)); // super
if (cc == NULL) 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; return NULL;
} }
shape->vtb = vtb;
struct _rect *rect = rect_new(width, height); struct _rect *rect = rect_new(width, height);
if(rect == NULL) if(rect == NULL)
{ {
return NULL; return NULL;
} }
cc->rect = rect;
struct _circle *circle = circle_new(radius); struct _circle *circle = circle_new(radius);
if (circle == NULL) if (circle == NULL)
{ {
return NULL; return NULL;
} }
cc->circle = circle;
cc->price = 100;
static struct _virtual_table vtb = { // self
.area = (double (*)(void *self, void *parent))copper_cash_area, struct _copper_cash *cc = calloc(1, sizeof(struct _copper_cash));
.draw = (void (*)(void *self, void *parent))copper_cash_draw, if (cc == NULL)
}; {
cc->shape.vtb = vtb; return NULL;
}
cc->price = 100;
// set parent
cc->shape = shape;
cc->rect = rect;
cc->circle = circle;
return cc; return cc;
} }
@ -256,20 +297,20 @@ int main(int argc, char *argv[])
circle_draw(circle, circle); circle_draw(circle, circle);
printf("----- rect & circle -----\n"); printf("----- rect & circle -----\n");
shape_area(rect, &rect->shape); shape_area(rect, rect->shape);
shape_draw(rect, &rect->shape); shape_draw(rect, rect->shape);
shape_area(circle, &circle->shape); shape_area(circle, circle->shape);
shape_draw(circle, &circle->shape); shape_draw(circle, circle->shape);
printf("----- [2] rect & circle -----\n"); printf("----- [2] rect & circle -----\n");
struct _rect *rect2 = (struct _rect *)rect_new(2, 3); struct _rect *rect2 = (struct _rect *)rect_new(2, 3);
shape_area(rect2, &rect2->shape); shape_area(rect2, rect2->shape);
shape_draw(rect2, &rect2->shape); shape_draw(rect2, rect2->shape);
struct _circle *circle2 = (struct _circle *)circle_new(1); struct _circle *circle2 = (struct _circle *)circle_new(1);
shape_area(circle2, &circle->shape); shape_area(circle2, circle->shape);
shape_draw(circle2, &circle->shape); shape_draw(circle2, circle->shape);
// printf("----- [2] shape -----\n"); // printf("----- [2] shape -----\n");
// struct _shape *shape = shape_new(); // struct _shape *shape = shape_new();
@ -278,8 +319,11 @@ int main(int argc, char *argv[])
printf("----- copper_cash -----\n"); printf("----- copper_cash -----\n");
struct _copper_cash *cc = copper_cash_new(2, 2, 4); struct _copper_cash *cc = copper_cash_new(2, 2, 4);
shape_area(cc, &cc->shape); shape_area(cc, cc->shape);
shape_draw(cc, &cc->shape); shape_draw(cc, cc->shape);
printf("----- [2] copper_cash -----\n");
rect_area(cc, cc->rect);
return 0; return 0;
} }