mirror of
https://gitee.com/apaki/cmake_demo.git
synced 2025-05-18 04:11:37 +08:00
C语言可以实现多态,但必须保证子类和父类相同的元素放在结构体最前面,且必须一模一样的排序。
This commit is contained in:
parent
2aca923437
commit
5d6d031a3a
20
main.c
20
main.c
@ -41,19 +41,19 @@ struct _virtual_table *virtual_new(void)
|
|||||||
|
|
||||||
struct _shape
|
struct _shape
|
||||||
{
|
{
|
||||||
struct _virtual_table *vtb;
|
struct _virtual_table vtb;
|
||||||
};
|
};
|
||||||
|
|
||||||
void shape_area(void *self)
|
void shape_area(void *self)
|
||||||
{
|
{
|
||||||
struct _shape *pthis = (struct _shape *)self;
|
struct _shape *pthis = (struct _shape *)self;
|
||||||
pthis->vtb->area(self);
|
pthis->vtb.area(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void shape_draw(void *self)
|
void shape_draw(void *self)
|
||||||
{
|
{
|
||||||
struct _shape *pthis = (struct _shape *)self;
|
struct _shape *pthis = (struct _shape *)self;
|
||||||
pthis->vtb->draw(self);
|
pthis->vtb.draw(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE void _shape_area(void *self)
|
PRIVATE void _shape_area(void *self)
|
||||||
@ -77,12 +77,10 @@ struct _shape *shape_new(void)
|
|||||||
.area = (void (*)(void *self))_shape_area,
|
.area = (void (*)(void *self))_shape_area,
|
||||||
.draw = (void (*)(void *self))_shape_draw
|
.draw = (void (*)(void *self))_shape_draw
|
||||||
};
|
};
|
||||||
shape->vtb = &vtb;
|
shape->vtb = vtb;
|
||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SUPER(self) (&(self)->shape)
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void shape_free(struct _shape * self)
|
void shape_free(struct _shape * self)
|
||||||
{
|
{
|
||||||
@ -96,7 +94,8 @@ void shape_free(struct _shape * self)
|
|||||||
struct _rect
|
struct _rect
|
||||||
{
|
{
|
||||||
// super
|
// super
|
||||||
struct _shape shape;
|
// struct _shape shape;
|
||||||
|
struct _virtual_table vtb;
|
||||||
|
|
||||||
// attribute
|
// attribute
|
||||||
double width, height;
|
double width, height;
|
||||||
@ -131,14 +130,15 @@ struct _rect *rect_new(double width, double height)
|
|||||||
.draw = (void (*)(void *self))rect_draw
|
.draw = (void (*)(void *self))rect_draw
|
||||||
};
|
};
|
||||||
|
|
||||||
SUPER(rect)->vtb = &vtb;
|
rect->vtb = vtb;
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _circle
|
struct _circle
|
||||||
{
|
{
|
||||||
// super
|
// super
|
||||||
struct _shape shape;
|
// struct _shape shape;
|
||||||
|
struct _virtual_table vtb;
|
||||||
|
|
||||||
// attribute
|
// attribute
|
||||||
double radius;
|
double radius;
|
||||||
@ -171,7 +171,7 @@ struct _circle *circle_new(double radius)
|
|||||||
.draw = (void (*)(void *self))circle_draw,
|
.draw = (void (*)(void *self))circle_draw,
|
||||||
};
|
};
|
||||||
|
|
||||||
SUPER(circle)->vtb = &vtb;
|
circle->vtb = vtb;
|
||||||
return circle;
|
return circle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user