mirror of
https://gitee.com/apaki/cmake_demo.git
synced 2025-05-17 20:01:36 +08:00
189 lines
3.3 KiB
C
189 lines
3.3 KiB
C
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
#define VIRTUAL
|
|
#define PRIVATE
|
|
|
|
struct _virtual_table
|
|
{
|
|
VIRTUAL void (*area)(void *self);
|
|
VIRTUAL void (*draw)(void *self);
|
|
};
|
|
|
|
void virtual_area(void *self)
|
|
{
|
|
assert(!"can't call abstract method");
|
|
}
|
|
|
|
void virtual_draw(void *self)
|
|
{
|
|
assert(!"can't call abstract method");
|
|
}
|
|
|
|
struct _virtual_table *virtual_new(void)
|
|
{
|
|
struct _virtual_table *v = calloc(1, sizeof(struct _virtual_table));
|
|
if (v == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
v->area = virtual_area;
|
|
v->draw = virtual_draw;
|
|
return v;
|
|
}
|
|
|
|
|
|
|
|
struct _shape
|
|
{
|
|
VIRTUAL void (*area)(void *self);
|
|
VIRTUAL void (*draw)(void *self);
|
|
};
|
|
|
|
void shape_area(void *self)
|
|
{
|
|
assert(!"can't call abstract method");
|
|
}
|
|
|
|
void shape_draw(void *self)
|
|
{
|
|
assert(!"can't call abstract method");
|
|
}
|
|
|
|
struct _shape *shape_new(void)
|
|
{
|
|
struct _shape *shape = calloc(1, sizeof(struct _shape));
|
|
if(shape == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
shape->area = shape_area;
|
|
shape->draw = shape_draw;
|
|
return shape;
|
|
}
|
|
|
|
#if 0
|
|
void shape_free(struct _shape * self)
|
|
{
|
|
if (self != NULL)
|
|
{
|
|
free(self);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#define SUPER(self) ((self)->shape)
|
|
|
|
struct _rect
|
|
{
|
|
// super
|
|
struct _shape* shape;
|
|
|
|
// attribute
|
|
double width, height;
|
|
|
|
// method
|
|
// void (*area)(void *self);
|
|
// void (*draw)(void *self);
|
|
};
|
|
|
|
void rect_area(struct _rect *self)
|
|
{
|
|
printf("rect area = %0.2f\n", self->width * self->height);
|
|
}
|
|
|
|
void rect_draw(struct _rect *self)
|
|
{
|
|
printf("rect draw\n");
|
|
}
|
|
|
|
struct _rect *rect_new(double width, double height)
|
|
{
|
|
struct _rect *rect = calloc(1, sizeof(struct _rect));
|
|
if (rect == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
rect->width = width;
|
|
rect->height = height;
|
|
|
|
rect->shape = shape_new();
|
|
if (rect->shape == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
SUPER(rect)->area = (void (*)(void *self))rect_area;
|
|
SUPER(rect)->draw = (void (*)(void *self))rect_draw;
|
|
return rect;
|
|
}
|
|
|
|
struct _circle
|
|
{
|
|
// super
|
|
struct _shape *shape;
|
|
|
|
// attribute
|
|
double radius;
|
|
|
|
// method
|
|
// void (*area)(void *self);
|
|
// void (*draw)(void *self);
|
|
};
|
|
|
|
void circle_area(struct _circle *self)
|
|
{
|
|
printf("circle area = %0.2f\n", 3.14 * self->radius * self->radius);
|
|
}
|
|
void circle_draw(struct _circle *self)
|
|
{
|
|
printf("circle draw\n");
|
|
}
|
|
|
|
struct _circle *circle_new(double radius)
|
|
{
|
|
struct _circle *circle = calloc(1, sizeof(struct _circle));
|
|
if (circle == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
circle->shape = shape_new();
|
|
if (circle->shape == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
circle->radius = radius;
|
|
|
|
SUPER(circle)->area = (void (*)(void *self))circle_area;
|
|
SUPER(circle)->draw = (void (*)(void *self))circle_draw;
|
|
return circle;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
struct _rect *rect = rect_new(4, 5);
|
|
rect_area(rect);
|
|
rect_draw(rect);
|
|
|
|
struct _circle *circle = circle_new(3);
|
|
circle_area(circle);
|
|
circle_draw(circle);
|
|
|
|
// struct shape *shape = shape_new();
|
|
// shape_area(shape);
|
|
// shape_draw(shape);
|
|
|
|
// struct _shape *shape = NULL;
|
|
struct _shape *shape = rect_new(2,3);
|
|
// shape = rect;
|
|
shape_area(shape);
|
|
shape_draw(shape);
|
|
|
|
return 0;
|
|
}
|