wly603

C模拟实现C++的多态

用c语言中的结构体模拟类,用函数指针模拟虚函数表。

整个程序用于模拟C++中的多态性,即用基类访问派生类的函数。

View Code
//  c语言模拟多态性

#include "stdio.h"
#include "stdlib.h"

enum ShapeType{CIRCLE,SQUARE,RECTANGLE};//形状类型


//建立虚函数表,2个虚函数
typedef struct  
{
    void (*ShowShape)();  
    double (*CalArea)(int w);
}vtable;

//建立基类
typedef struct
{
    vtable *vptr_base;
    ShapeType  type;
}BaseShape;


//建立三个派生类
typedef struct
{
    BaseShape  itsType;
    int r;
}Circle;

typedef struct
{
    BaseShape itsType;
    int w;
}Square;

typedef struct  
{
    BaseShape itsType;
    int w,h;
}Rectangle;

//子类重写虚函数 
//Circle
void showCircle()
{
    printf("I'm a Circle!\n");
}

double calArea_Circle(int r)
{
    return 3.14*r*r;
}

//Square
void showSquare()
{
    printf("I'm a Square!\n");
}

double calArea_Square(int w)
{
    return w*w;
}


//Rectangle
void showRectangle()
{
    printf("I'm a Rectangle!\n");
}

double calArea_Rectangle(int w)
{
    return w*w*2;  //假设高是宽的2倍
}

//测验多态,只需要传递基类指针ShapePointer。  
void virtualShow(BaseShape *base)
{
    base->vptr_base->ShowShape();
}

void virtualCalArea(BaseShape *base, int w)
{
    printf("     面积为: %2.2f\n", base->vptr_base->CalArea(w));
}

////////////////////////////////////////////////////
void main()
{
    Circle m_c = {(vtable *)malloc(sizeof(vtable)), CIRCLE, 1};
    Square m_s = {(vtable *)malloc(sizeof(vtable)), SQUARE, 1};
    Rectangle m_r = {(vtable *)malloc(sizeof(vtable)), RECTANGLE, 1,2};

    printf("圆的半径为1,正方形的宽为1,长方形的宽高分别为1,2\n");

    //各子类对象的虚函数表初始化
    m_c.itsType.vptr_base->ShowShape = showCircle;
    m_c.itsType.vptr_base->CalArea = calArea_Circle;

    m_s.itsType.vptr_base->ShowShape = showSquare;
    m_s.itsType.vptr_base->CalArea = calArea_Square;

    m_r.itsType.vptr_base->ShowShape = showRectangle;
    m_r.itsType.vptr_base->CalArea = calArea_Rectangle;

    //基类指针指向派生类
    BaseShape *pB_c = (BaseShape *)&m_c;
    BaseShape *pB_s = (BaseShape *)&m_s;
    BaseShape *pB_r = (BaseShape *)&m_r;

    //测试多态性
    virtualShow(pB_c);
    virtualCalArea(pB_c,1);

    virtualShow(pB_s);
    virtualCalArea(pB_s,1);

    virtualShow(pB_r);
    virtualCalArea(pB_r,1);
    



}

posted on 2012-04-11 10:36  wly603  阅读(1513)  评论(0编辑  收藏  举报

导航