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