一个用C来模拟类的多态行为的例子
黄国强 2009-8-21
在某些嵌入式系统中不支持类的概念,下面介绍了一个例子来说明如何在C中实现多态。
1) 这是原先C的代码:
enum Shape
{
LINE = 0,CIRCLE,RECT,
};
struct Line
{
int x1,y1,x2,y2;
};
struct Circle
{
int x,y,rad;
};
struct Rect
{
int left,right,top,bottom;
};
void DrawLine(Line * pLine);
void DrawCircle(Circle * pCircle);
void DrawRect(Rect * pRect);
void Draw(Shape eType,void * pShape)
{
swtich(eType)
{
case LINE:
DrawLine((Line *)pShape));
break;
case CIRCLE:
DrawCircle((Circle *)pShape);
break;
case RECT:
DrawCircle((Rect *)pShape);
break;
default:
break;
}
}
2) 这是改进后的代码:
enum ShapeType
{
LINE = 0,CIRCLE,RECT,
};
typedef struct tagShape
{
void (* Draw)(void * pShape);
void * pShape;
} Shape;
typedef struct tagLine
{
int x1,y1,x2,y2;
} Line;
typedef struct tagCircle
{
int x,y,rad;
} Circle;
typedef struct tagRect
{
int left,right,top,bottom;
} Rect;
void DrawLine(void * p)
{
Line * pLine = (Line *)p;
// 具体绘制代码
}
void DrawCircle(void * p)
{
Circle * pCircle = (Circle *)p;
// 具体绘制代码
}
void DrawRect(void * p)
{
Rect * pRect = (Rect *)p;
// 具体绘制代码
}
// 工厂函数。只有这里的switch是允许的
Shape CreateShape(ShapeType eType,void * pShape)
{
Shape aShape;
aShape.pShape = pShape;
switch(eType)
{
case LINE:
aShape.Draw = DrawLine;
break;
case CIRCLE:
aShape.Draw = DrawCircle;
break;
case RECT:
aShape.Draw = DrawRect;
break;
default:
aShape.Draw = NULL;
break;
}
return aShape;
}
int _tmain(int argc, _TCHAR* argv[])
{
Rect rect;
rect.top = 0;
rect.left = 0;
rect.right = 100;
rect.bottom = 100;
Shape aShape = CreateShape(RECT,&rect);
aShape.Draw(aShape.pShape);
system("Pause");
return 0;
}
改进后的代码运用了函数指针的技术。