注:这个程序是在软件设计师教程上看到,并做了一点点修改得到。。
在一个简化的绘图程序中,支持点(point)和圆(circle)两种图形,在设计过程中采用面向对象思想,认为所有的点和圆都是一种图形(shape),
并定义类型shape_t、point_t、circle_t分别表示基本图形、点和圆,点和圆自然具有基本图形的所有特征。
下面是利用C语言,通过函数指针和可变参数机制实现上面的类层次关系:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
// 程序中的两个图形:点和圆
typedef enum {point,circle}shape_type;
// 基本图形类型
typedef struct {
shape_type type;
void (*destroy)();
void (*draw)();
}shape_t;
// 点类
typedef struct {
shape_t common;
int x,y;
}point_t;
// 圆类
typedef struct {
shape_t common;
point_t *center;
int radius;
}circle_t;
/*
下面是相关方法*/
void destroyPoint(point_t *this)
{
int x=this->x,y=this->y;
free(this);
printf("P(%d,%d) destroyed!\n",x,y);
}
void drawPoint(point_t *this)
{
printf("P(%d,%d)",this->x,this->y);
}
point_t * createPoint(va_list *ap)
{
point_t *p_point;
if ((p_point=(point_t*)malloc(sizeof (point_t)))==NULL)
return NULL;
p_point->common.type=point;
p_point->common.destroy=destroyPoint;
p_point->common.draw=drawPoint;
p_point->x=va_arg(*ap,int);
p_point->y=va_arg(*ap,int);
return p_point;
}
void destroyCircle(circle_t *this)
{
int x=this->center->x;
int y=this->center->y;
int r=this->radius;
this->center->common.destroy(this->center);
free(this);
printf("C(P(%d,%d),%d) destroyed!\n",x,y,r);
}
void drawCircle(circle_t *this)
{
printf("C(");
this->center->common.draw(this->center);
printf(",%d)",this->radius);
}
circle_t* createCircle(va_list* ap)
{
circle_t *p_circle;
if ((p_circle=(circle_t*)malloc(sizeof(circle_t)))==NULL)
return NULL;
p_circle->common.type=circle;
p_circle->common.destroy=destroyCircle;
p_circle->common.draw=drawCircle;
p_circle->center=createPoint(ap);
p_circle->radius=va_arg(*ap,int);
return p_circle;
}
shape_t* createShape(shape_type st,...)
{
va_list ap;
shape_t* p_shape=NULL;
va_start(ap,st);
if (st==point) p_shape=(shape_t*)createPoint(&ap);
if (st==circle) p_shape=(shape_t*)createCircle(&ap);
va_end(ap);
return p_shape;
}
int main()
{
int i;
shape_t *shapes[2];
shapes[0]=createShape(point,2,3);
shapes[1]=createShape(circle,20,40,10);
for (i=0;i<2;i++) {
shapes[i]->draw(shapes[i]);
printf("\n");
}
for (i=1;i>=0;i--)
shapes[i]->destroy(shapes[i]);
return 0;
}