实测发现还是不行了,container_of再强大,也无法推断出这个呀。

This commit is contained in:
建峰 2024-09-01 18:02:19 +08:00
parent 42d305eabe
commit 37ea937147
9 changed files with 60 additions and 61 deletions

View File

@ -1,21 +1,21 @@
#include "circle.h" #include "circle.h"
double circle_area(void *self, void *parent) double circle_area(void *self)
{ {
double area = 0; double area = 0;
struct _circle *pthis = (struct _circle *)parent; struct _circle *pthis = container_of(self, struct _circle, me);
area = pthis->shape->vtb.area(self, NULL); area = pthis->shape->vtb.area(pthis);
return area; return area;
} }
void circle_draw(void *self, void *parent) void circle_draw(void *self)
{ {
struct _circle *pthis = (struct _circle *)parent; struct _circle *pthis = container_of(self, struct _circle, me);
pthis->shape->vtb.draw(self, NULL); pthis->shape->vtb.draw(pthis);
} }
double _circle_area(void *self, void *parent) double _circle_area(void *self)
{ {
struct _circle *pthis = (struct _circle *)self; struct _circle *pthis = (struct _circle *)self;
double area = 3.14 * pthis->radius * pthis->radius; double area = 3.14 * pthis->radius * pthis->radius;
@ -32,8 +32,8 @@ struct _circle *circle_new(double radius)
{ {
// super // super
static struct _virtual_table vtb = { static struct _virtual_table vtb = {
.area = (double (*)(void *self, void *parent))_circle_area, .area = (double (*)(void *self))_circle_area,
.draw = (void (*)(void *self, void *parent))_circle_draw, .draw = (void (*)(void *self))_circle_draw,
}; };
struct _shape *shape = shape_new(); struct _shape *shape = shape_new();
@ -49,6 +49,7 @@ struct _circle *circle_new(double radius)
{ {
return NULL; return NULL;
} }
circle->me = circle;
circle->radius = radius; circle->radius = radius;
// set parent // set parent
circle->shape = shape; circle->shape = shape;

View File

@ -7,7 +7,7 @@
struct _circle struct _circle
{ {
int invalid; struct _circle *me;
// super // super
struct _shape *shape; struct _shape *shape;
@ -22,7 +22,7 @@ struct _circle
struct _circle *circle_new(double radius); struct _circle *circle_new(double radius);
double circle_area(void *self, void *parent); double circle_area(void *self);
void circle_draw(void *self, void *parent); void circle_draw(void *self);
#endif #endif

View File

@ -27,8 +27,8 @@ struct _copper_cash *copper_cash_new(double width, double height, double radius)
{ {
// super // super
static struct _virtual_table vtb = { static struct _virtual_table vtb = {
.area = (double (*)(void *self, void *parent))copper_cash_area, .area = (double (*)(void *self))copper_cash_area,
.draw = (void (*)(void *self, void *parent))copper_cash_draw, .draw = (void (*)(void *self))copper_cash_draw,
}; };
struct _shape *shape = shape_new(); struct _shape *shape = shape_new();
@ -58,7 +58,7 @@ struct _copper_cash *copper_cash_new(double width, double height, double radius)
{ {
return NULL; return NULL;
} }
cc->self = cc; cc->me = cc;
cc->price = 100; cc->price = 100;
// set parent // set parent

View File

@ -9,7 +9,7 @@
struct _copper_cash struct _copper_cash
{ {
struct _copper_cash *self; struct _copper_cash *me;
struct _shape *shape; struct _shape *shape;
struct _rect *rect; struct _rect *rect;

View File

@ -1,24 +1,21 @@
#include "rect.h" #include "rect.h"
double rect_area(void *self, void *parent) double rect_area(void *self)
{ {
double area = 0; double area = 0;
struct _rect *pthis = (struct _rect *)parent; struct _rect *pthis = container_of(self, struct _rect, me);
area = pthis->shape->vtb.area(self, NULL); area = pthis->shape->vtb.area(pthis);
return area; return area;
} }
void rect_draw(void *self, void *parent) void rect_draw(void *self)
{ {
// struct _rect *pthis = (struct _rect *)parent; struct _rect *pthis = container_of(self, struct _rect, me);
// pthis->shape->vtb.draw(self, NULL); pthis->shape->vtb.draw(pthis);
struct _rect *pthis = container_of(parent, struct _rect, self);
pthis->shape->vtb.draw(pthis, NULL);
} }
double _rect_area(void *self, void *parent) double _rect_area(void *self)
{ {
struct _rect *pthis = (struct _rect *)self; struct _rect *pthis = (struct _rect *)self;
double area = pthis->width * pthis->height; double area = pthis->width * pthis->height;
@ -27,7 +24,7 @@ double _rect_area(void *self, void *parent)
return area; return area;
} }
void _rect_draw(void *self, void *parent) void _rect_draw(void *self)
{ {
printf("rect draw\n"); printf("rect draw\n");
} }
@ -36,8 +33,8 @@ struct _rect *rect_new(double width, double height)
{ {
// super // super
static struct _virtual_table vtb = { static struct _virtual_table vtb = {
.area = (double (*)(void *self, void *parent))_rect_area, .area = (double (*)(void *self))_rect_area,
.draw = (void (*)(void *self, void *parent))_rect_draw, .draw = (void (*)(void *self))_rect_draw,
}; };
struct _shape *shape = shape_new(); struct _shape *shape = shape_new();
@ -53,7 +50,7 @@ struct _rect *rect_new(double width, double height)
{ {
return NULL; return NULL;
} }
rect->self = rect; rect->me = rect;
rect->width = width; rect->width = width;
rect->height = height; rect->height = height;

View File

@ -8,7 +8,7 @@
struct _rect struct _rect
{ {
// int invalid; // int invalid;
struct _rect *self; struct _rect *me;
// super // super
struct _shape *shape; struct _shape *shape;
@ -19,7 +19,7 @@ struct _rect
struct _rect *rect_new(double width, double height); struct _rect *rect_new(double width, double height);
double rect_area(void *self, void *parent); double rect_area(void *self);
void rect_draw(void *self, void *parent); void rect_draw(void *self);
#endif #endif

View File

@ -1,12 +1,12 @@
#include "shape.h" #include "shape.h"
double virtual_area(void *self, void *parent) double virtual_area(void *self)
{ {
ASSERT_CALL_VIRTUAL_METHOD(); ASSERT_CALL_VIRTUAL_METHOD();
} }
void virtual_draw(void *self, void *parent) void virtual_draw(void *self)
{ {
ASSERT_CALL_VIRTUAL_METHOD(); ASSERT_CALL_VIRTUAL_METHOD();
} }
@ -25,26 +25,26 @@ struct _virtual_table *virtual_new(void)
double shape_area(void *self, void *parent) double shape_area(void *self)
{ {
double area = 0; double area = 0;
struct _shape *pthis = (struct _shape *)parent; struct _shape *pthis = container_of(self, struct _shape, me);
area = pthis->vtb.area(self, NULL); area = pthis->vtb.area(pthis);
return area; return area;
} }
void shape_draw(void *self, void *parent) void shape_draw(void *self)
{ {
struct _shape *pthis = (struct _shape *)parent; struct _shape *pthis = container_of(self, struct _shape, me);
pthis->vtb.draw(self, NULL); pthis->vtb.draw(pthis);
} }
PRIVATE double _shape_area(void *self, void *parent) PRIVATE double _shape_area(void *self)
{ {
ASSERT_CALL_VIRTUAL_METHOD(); ASSERT_CALL_VIRTUAL_METHOD();
} }
PRIVATE void _shape_draw(void *self, void *parent) PRIVATE void _shape_draw(void *self)
{ {
ASSERT_CALL_VIRTUAL_METHOD(); ASSERT_CALL_VIRTUAL_METHOD();
} }
@ -56,11 +56,11 @@ struct _shape *shape_new(void)
{ {
return NULL; return NULL;
} }
shape->self = shape; shape->me = shape;
static struct _virtual_table vtb = { static struct _virtual_table vtb = {
.area = (double (*)(void *self, void *parent))_shape_area, .area = (double (*)(void *self))_shape_area,
.draw = (void (*)(void *self, void *parent))_shape_draw .draw = (void (*)(void *self))_shape_draw
}; };
shape->vtb = vtb; shape->vtb = vtb;
return shape; return shape;

View File

@ -11,13 +11,13 @@
struct _virtual_table struct _virtual_table
{ {
VIRTUAL double (*area)(void *self, void *parent); VIRTUAL double (*area)(void *self);
VIRTUAL void (*draw)(void *self, void *parent); VIRTUAL void (*draw)(void *self);
}; };
struct _shape struct _shape
{ {
struct _shape *self; struct _shape *me;
struct _virtual_table vtb; struct _virtual_table vtb;
}; };
@ -25,8 +25,8 @@ struct _shape
struct _shape *shape_new(void); struct _shape *shape_new(void);
double shape_area(void *self, void *parent); double shape_area(void *self);
void shape_draw(void *self, void *parent); void shape_draw(void *self);
#endif #endif

View File

@ -7,20 +7,21 @@
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); rect_area(rect);
rect_draw(rect, rect); rect_draw(rect);
struct _circle *circle = circle_new(3); struct _circle *circle = circle_new(2);
circle_area(circle, circle); circle_area(circle);
circle_draw(circle, circle); circle_draw(circle);
printf("----- rect & circle -----\n"); printf("----- rect & circle -----\n");
shape_area(rect, rect->shape); shape_area(rect->shape);
shape_draw(rect, rect->shape); shape_draw(rect->shape);
shape_area(circle, circle->shape); shape_area(circle->shape);
shape_draw(circle, circle->shape); shape_draw(circle->shape);
#if 0
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);
@ -46,6 +47,6 @@ int main(int argc, char *argv[])
circle_area(cc, cc->circle); circle_area(cc, cc->circle);
circle_draw(cc, cc->circle); circle_draw(cc, cc->circle);
#endif
return 0; return 0;
} }