Created
January 3, 2014 08:31
-
-
Save draftcode/8234778 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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