Interfaces
This commit is contained in:
parent
7ffb1f122e
commit
89abb3ac10
1 changed files with 70 additions and 0 deletions
70
interfaces.c
Normal file
70
interfaces.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Here's a basic interface for geometric shapes.
|
||||
typedef struct {
|
||||
double (*area)(void *);
|
||||
double (*perim)(void *);
|
||||
} geometry;
|
||||
|
||||
// For our example we'll implement this interface on
|
||||
// `rect` and `circle` types.
|
||||
typedef struct {
|
||||
double width, height;
|
||||
} rect;
|
||||
|
||||
typedef struct {
|
||||
double radius;
|
||||
} circle;
|
||||
|
||||
// To implement an interface in C, we need to define functions
|
||||
// that match the function pointers in the interface.
|
||||
// Here we implement `geometry` on `rect`s.
|
||||
double rect_area(void *r) {
|
||||
rect *rect_ptr = (rect *)r;
|
||||
return rect_ptr->width * rect_ptr->height;
|
||||
}
|
||||
|
||||
double rect_perim(void *r) {
|
||||
rect *rect_ptr = (rect *)r;
|
||||
return 2 * rect_ptr->width + 2 * rect_ptr->height;
|
||||
}
|
||||
|
||||
// The implementation for `circle`s.
|
||||
double circle_area(void *c) {
|
||||
circle *circle_ptr = (circle *)c;
|
||||
return M_PI * circle_ptr->radius * circle_ptr->radius;
|
||||
}
|
||||
|
||||
double circle_perim(void *c) {
|
||||
circle *circle_ptr = (circle *)c;
|
||||
return 2 * M_PI * circle_ptr->radius;
|
||||
}
|
||||
|
||||
// If a variable has an interface type, then we can call
|
||||
// methods that are in the named interface. Here's a
|
||||
// generic `measure` function taking advantage of this
|
||||
// to work on any `geometry`.
|
||||
void measure(void *g, geometry *geom) {
|
||||
printf("Area: %f\n", geom->area(g));
|
||||
printf("Perimeter: %f\n", geom->perim(g));
|
||||
}
|
||||
|
||||
int main() {
|
||||
rect r = {.width = 3, .height = 4};
|
||||
circle c = {.radius = 5};
|
||||
|
||||
// The `circle` and `rect` struct types both
|
||||
// implement the `geometry` interface so we can use
|
||||
// instances of these structs as arguments to `measure`.
|
||||
geometry rect_geometry = {rect_area, rect_perim};
|
||||
geometry circle_geometry = {circle_area, circle_perim};
|
||||
|
||||
printf("Rectangle:\n");
|
||||
measure(&r, &rect_geometry);
|
||||
|
||||
printf("\nCircle:\n");
|
||||
measure(&c, &circle_geometry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue