C语言可以实现多态,但必须保证子类和父类相同的元素放在结构体最前面,且必须一模一样的排序。

This commit is contained in:
建峰 2024-09-01 13:36:12 +08:00
parent 2aca923437
commit 5d6d031a3a

20
main.c
View File

@ -41,19 +41,19 @@ struct _virtual_table *virtual_new(void)
struct _shape
{
struct _virtual_table *vtb;
struct _virtual_table vtb;
};
void shape_area(void *self)
{
struct _shape *pthis = (struct _shape *)self;
pthis->vtb->area(self);
pthis->vtb.area(self);
}
void shape_draw(void *self)
{
struct _shape *pthis = (struct _shape *)self;
pthis->vtb->draw(self);
pthis->vtb.draw(self);
}
PRIVATE void _shape_area(void *self)
@ -77,12 +77,10 @@ struct _shape *shape_new(void)
.area = (void (*)(void *self))_shape_area,
.draw = (void (*)(void *self))_shape_draw
};
shape->vtb = &vtb;
shape->vtb = vtb;
return shape;
}
#define SUPER(self) (&(self)->shape)
#if 0
void shape_free(struct _shape * self)
{
@ -96,7 +94,8 @@ void shape_free(struct _shape * self)
struct _rect
{
// super
struct _shape shape;
// struct _shape shape;
struct _virtual_table vtb;
// attribute
double width, height;
@ -131,14 +130,15 @@ struct _rect *rect_new(double width, double height)
.draw = (void (*)(void *self))rect_draw
};
SUPER(rect)->vtb = &vtb;
rect->vtb = vtb;
return rect;
}
struct _circle
{
// super
struct _shape shape;
// struct _shape shape;
struct _virtual_table vtb;
// attribute
double radius;
@ -171,7 +171,7 @@ struct _circle *circle_new(double radius)
.draw = (void (*)(void *self))circle_draw,
};
SUPER(circle)->vtb = &vtb;
circle->vtb = vtb;
return circle;
}