Skip to content

Instantly share code, notes, and snippets.

@draftcode
Created January 3, 2014 08:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save draftcode/8234778 to your computer and use it in GitHub Desktop.
Save draftcode/8234778 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#pragma pack(8)
struct shape_vtbl;
typedef struct {
double x, y;
struct shape_vtbl *shape_vtbl;
} SHAPE;
struct shape_vtbl {
// void (*move)(void *self, double dx, double dy);
// double (*area)(void *self);
void *move;
void *area;
};
void SHAPE_move(void *_self, double dx, double dy) {
SHAPE *self = _self;
self->x += dx;
self->x += dy;
}
void *init_SHAPE(void *_self, double x, double y) {
SHAPE *self = _self;
if (!self) return self;
self->shape_vtbl = malloc(sizeof(struct shape_vtbl));
if (!self->shape_vtbl) return NULL;
self->x = x;
self->y = y;
self->shape_vtbl->move = SHAPE_move;
self->shape_vtbl->area = NULL;
return self;
}
typedef struct {
SHAPE parent;
double h, w;
} TRIANGLE;
double TRIANGLE_area(void *_self) {
TRIANGLE *self = _self;
return self->h * self->w / 2;
}
void *init_TRIANGLE(void *_self, double x, double y, double h, double w) {
TRIANGLE *self = (TRIANGLE *)init_SHAPE(_self, x, y);
if (!self) return self;
self->h = h;
self->w = w;
self->parent.shape_vtbl->area = TRIANGLE_area;
return self;
}
typedef struct {
SHAPE parent;
double h, w;
} RECTANGLE;
double RECTANGLE_area(void *_self) {
RECTANGLE *self = _self;
return self->h * self->w;
}
void *init_RECTANGLE(void *_self, double x, double y, double h, double w) {
RECTANGLE *self = init_SHAPE(_self, x, y);
if (!self) return self;
self->h = h;
self->w = w;
self->parent.shape_vtbl->area = RECTANGLE_area;
return self;
}
typedef struct {
SHAPE parent;
double r;
} CIRCLE;
double CIRCLE_area(void *_self) {
CIRCLE *self = _self;
return self->r * self->r * 3.14;
}
void *init_CIRCLE(void *_self, double x, double y, double r) {
CIRCLE *self = init_SHAPE(_self, x, y);
if (!self) return self;
self->r = r;
self->parent.shape_vtbl->area = CIRCLE_area;
return self;
}
int main(void) {
SHAPE *triangle = malloc(sizeof(TRIANGLE));
if (!init_TRIANGLE(triangle, 0.0, 0.0, 1.0, 1.0)) abort();
SHAPE *rect = malloc(sizeof(RECTANGLE));
if (!init_RECTANGLE(rect, 0.0, 0.0, 1.0, 1.0)) abort();
SHAPE *circle = malloc(sizeof(CIRCLE));
if (!init_CIRCLE(circle, 0.0, 0.0, 1.0)) abort();
double (*area)(void *self);
area = triangle->shape_vtbl->area;
printf("TRIANGLE.size() = %f\n", area(rect));
area = rect->shape_vtbl->area;
printf("RECT.size() = %f\n", area(rect));
area = circle->shape_vtbl->area;
printf("CIRCLE.size() = %f\n", area(rect));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment