//C has no inheritance: the base struct is the first field,
//and a pointer to a function plays the virtual method
typedef struct Shape {
const char *name;
double (*area)(const struct Shape *self);
} Shape;
typedef struct {
Shape base;
double width, height;
} Rect;
typedef struct {
Shape base;
double radius;
} Circle;
//base is the first field, so a Shape * points to the whole Rect
double rectArea(const Shape *self) {
const Rect *rect = (const Rect *)self;
return rect->width * rect->height;
}
double circleArea(const Shape *self) {
const Circle *circle = (const Circle *)self;
return M_PI * circle->radius * circle->radius;
}
Rect rect = {{"rect", rectArea}, 2, 3};
Circle circle = {{"circle", circleArea}, 1};
//the code sees only Shape, each shape computes the area its own way
Shape *shapes[] = {&rect.base, &circle.base};
const char *name = shapes[1]->name;
//name is "circle"
double area0 = shapes[0]->area(shapes[0]);
//area0 is 6
double area1 = shapes[1]->area(shapes[1]);
//area1 is 3.14159
printf("name is %s\n", name);
printf("area0 is %g\n", area0);
printf("area1 is %g\n", area1);