1. 抽象的shape类
/*************************************************************************
> File Name: shape.h
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Thu 12 Sep 2019 01:59:14 PM CST
************************************************************************/
#ifndef _SHAPE_H
#define _SHAPE_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct shape_vtbl;
struct shape {
const struct shape_vtbl* vptr; ///< virtual table pointer
int x; ///< x coordinate of shape's position
int y; ///< y coordinate of shape's position
};
///< virtual method table
struct shape_vtbl {
uint32_t (*area)(const struct shape* const pthis);
void (*draw)(const struct shape* const pthis);
};
extern void shape_static_ctor(struct shape* const pthis, int x, int y);
extern void shape_moveby(struct shape* const pthis, int dx, int dy);
extern int shape_getx(struct shape const *pthis);
extern int shape_gety(struct shape const *pthis);
extern struct shape const* largest_shape(const struct shape* shapes[], uint32_t nshapes);
extern void draw_all_shapes(const struct shape* shapes[], uint32_t nshapes);
///< virtual method
extern uint32_t shape_area(const struct shape* const pthis);
extern void shape_draw(const struct shape* const pthis);
#ifdef __cplusplus
}
#endif
#endif // _SHAPE_H
/*************************************************************************
> File Name: shape.c
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Thu 12 Sep 2019 02:31:42 PM CST
************************************************************************/
#include <stdio.h>
#include "shape.h"
///< virtual base class virtual method: do nothing!
//static inline void shape_draw_(const struct shape* const pthis);
//static inline uint32_t shape_area_(const struct shape* const pthis);
void shape_static_ctor(struct shape* const pthis, int x, int y)
{
static struct shape_vtbl vtbl = {
.area = NULL /*shape_area_*/,
.draw = NULL /*shape_draw_*/,
};
pthis->vptr = &vtbl;
pthis->x = x;
pthis->y = y;
}
void shape_moveby(struct shape* const pthis, int dx, int dy)
{
pthis->x += dx;
pthis->y += dy;
}
int shape_getx(struct shape const *pthis)
{
return pthis->x;
}
int shape_gety(struct shape const *pthis)
{
return pthis->y;
}
///< virtual method
inline uint32_t shape_area(const struct shape* const pthis)
{
return (*pthis->vptr->area)(pthis);
}
///< virtual method
inline void shape_draw(const struct shape* const pthis)
{
(*pthis->vptr->draw)(pthis);
}
/*
static inline uint32_t shape_area_(const struct shape* const pthis)
{
assert(0);
return 0U;
}
static inline void shape_draw_(const struct shape* const pthis)
{
assert(0);
}
*/
struct shape const* largest_shape(const struct shape* shapes[], uint32_t nshapes)
{
const struct shape* s = NULL;
uint32_t max = 0U;
for (uint32_t i = 0U; i < nshapes; i++) {
uint32_t area = shape_area(shapes[i]);
if (area > max)
max = area;
s = shapes[i];
}
return s;
}
void draw_all_shapes(const struct shape* shapes[], uint32_t nshapes)
{
for (uint32_t i = 0U; i < nshapes; i++) {
shape_draw(shapes[i]);
}
}
2. 派生类rectangle
/*************************************************************************
> File Name: rectangle.h
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Thu 12 Sep 2019 02:15:31 PM CST
************************************************************************/
#ifndef _RECTANGLE_H
#define _RECTANGLE_H
#include <stdint.h>
#include "shape.h"
#ifdef __cplusplus
extern "C" {
#endif
struct rectangle {
struct shape super;
uint32_t width;
uint32_t height;
};
extern void rectangle_static_ctor(struct rectangle* const pthis, int x, int y, uint32_t w, uint32_t h);
extern struct rectangle* rectangle_dynamic_ctor(int x, int y, uint32_t w, uint32_t h);
extern void rectangle_dynamic_dtor(struct rectangle** pthis);
///< virtual method override
extern void rectangle_draw_override(const struct shape* const pthis);
extern uint32_t rectangle_area_override(const struct shape* const pthis);
#ifdef __cplusplus
}
#endif
#endif // _RECTANGLE_H
/*************************************************************************
> File Name: rectangle.c
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Thu 12 Sep 2019 02:33:35 PM CST
************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "rectangle.h"
void rectangle_static_ctor(struct rectangle* const pthis, int x, int y, uint32_t w, uint32_t h)
{
static struct shape_vtbl const vtbl = {
.draw = rectangle_draw_override,
.area = rectangle_area_override,
};
shape_static_ctor(&pthis->super, x, y);
pthis->super.vptr = &vtbl;
pthis->width = w;
pthis->height = h;
}
struct rectangle* rectangle_dynamic_ctor(int x, int y, uint32_t w, uint32_t h)
{
struct rectangle* pthis = malloc(sizeof(struct rectangle));
rectangle_static_ctor(pthis, x, y, w, h);
return pthis;
}
void rectangle_dynamic_dtor(struct rectangle** pthis)
{
free(*pthis);
}
void rectangle_draw_override(const struct shape* const pthis)
{
const struct rectangle* const pthis_ = (const struct rectangle*)pthis;
printf("rectangle draw: x = %d, y = %d, width = %d, height = %d\n",
pthis->x, pthis->y, pthis_->width, pthis_->height);
}
uint32_t rectangle_area_override(const struct shape* const pthis)
{
const struct rectangle* const pthis_ = (const struct rectangle*)pthis;
return pthis_->width * pthis_->height;
}
3. 派生类circle
/*************************************************************************
> File Name: circle.h
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Thu 12 Sep 2019 02:21:04 PM CST
************************************************************************/
#ifndef _CIRCLE_H
#define _CIRCLE_H
#include <stdint.h>
#include "shape.h"
#ifdef __cplusplus
extern "C" {
#endif
struct circle {
struct shape super;
uint32_t radius;
};
extern void circle_static_ctor(struct circle* const pthis, int x, int y, uint32_t r);
extern struct circle* circle_dynamic_ctor(int x, int y, uint32_t r);
extern void circle_dynamic_dtor(struct circle** pthis);
///< virtual method override
extern void circle_draw_override(const struct shape* const pthis);
extern uint32_t circle_area_override(const struct shape* const pthis);
#ifdef __cplusplus
}
#endif
#endif // _CIRCLE_H
/*************************************************************************
> File Name: circle.c
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Thu 12 Sep 2019 02:34:39 PM CST
************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "circle.h"
void circle_static_ctor(struct circle* const pthis, int x, int y, uint32_t r)
{
static struct shape_vtbl const vtbl = {
.draw = circle_draw_override,
.area = circle_area_override,
};
shape_static_ctor(&pthis->super, x, y);
pthis->super.vptr = &vtbl;
pthis->radius = r;
}
struct circle* circle_dynamic_ctor(int x, int y, uint32_t r)
{
struct circle* pthis = malloc(sizeof(struct circle));
circle_static_ctor(pthis, x, y, r);
return pthis;
}
void circle_dynamic_dtor(struct circle** pthis)
{
free(*pthis);
}
void circle_draw_override(const struct shape* const pthis)
{
const struct circle* const pthis_ = (const struct circle*)pthis;
printf("circle draw: x = %d, y = %d, radius = %d\n",
pthis->x, pthis->y, pthis_->radius);
}
uint32_t circle_area_override(const struct shape* const pthis)
{
const struct circle* const pthis_ = (const struct circle*)pthis;
return (uint32_t)(3.1415926 * pthis_->radius * pthis_->radius);
}
4. 测试用例
/*************************************************************************
> File Name: test_oopc.c
> Author: XXDK
> Email: v.manstein@qq.com
> Created Time: Wed 11 Sep 2019 05:30:38 PM PDT
************************************************************************/
#include<stdio.h>
#include<stdint.h>
#include<assert.h>
#include<stdlib.h>
#include"shape.h"
#include"rectangle.h"
#include"circle.h"
int main()
{
struct rectangle r1;
rectangle_static_ctor(&r1, 20, 20, 20, 20);
struct rectangle* r2 = rectangle_dynamic_ctor(40, 40, 40, 40);
struct circle c1;
circle_static_ctor(&c1, 60, 60, 20);
struct circle* c2 = circle_dynamic_ctor(80, 80, 40);
rectangle_draw_override((struct shape*)&r1); ///< call override virtual method
rectangle_draw_override((struct shape*)r2);
circle_draw_override((struct shape*)&c1);
circle_draw_override((struct shape*)c2);
//const struct shape* sa[] = {&r1.super, &r2.super, &r3->super};
const struct shape* sa[] = {(struct shape*)&r1, (struct shape*)r2,
(struct shape*)&c1, (struct shape*)c2};
struct shape const *s = largest_shape(sa, sizeof(sa)/sizeof(sa[0]));
printf("largest shape: x = %d, y = %d, area = %d\n", shape_getx(s), shape_gety(s), shape_area(s));
rectangle_dynamic_dtor(&r2);
circle_dynamic_dtor(&c2);
return 0;
}
5. 编译
# set envrionment
CC=gcc
CC_FLAGS=-D_FILELINE
SRCS=$(wildcard *.c */*.c)
#set inc and lib
INCS=-I .
LIBS=-lpthread -L.
TARGET=test_oopc
OBJS=$(patsubst %.c, %.o, $(SRCS))
all:$(TARGET)
$(TARGET):$(OBJS)
$(CC) -o $@ $^ $(LIBS)
%.o:%.c
$(CC) $(CC_FLAGS) $(INCS) $(LIBS) -c -g $< -o $@
.PHONY: install clean
install:
clean:
rm $(TARGET) $(OBJS)