您的位置:首页 > 编程语言 > C语言/C++

用c语言实现面向对象的封装继承和多态

2014-09-07 09:38 661 查看
#include<string>
#include<iostream>
using namespace std;

struct Shape;
typedef const string& (*GetName)(Shape* shape);
typedef void (*Draw)(Shape* shape);

typedef struct VTable{//虚表的定义
GetName getName;
Draw draw;
}VTable;

const string& getNameTriangle(Shape* shape);
const string& getNameCircle(Shape* shape);
void drawTriangle(Shape* shape);
void drawCircle(Shape* shape);

static VTable vtableTriangle={getNameTriangle,drawTriangle};//初始化虚表
static VTable vtableCircle={getNameCircle,drawCircle};

typedef struct Shape{//定义基类形状
string name;
VTable* vptr;
}Shape;

//下面两个宏定义用来得到实际的指针
#define OFFSET(TYPE,MEMBER) ((unsigned int)&(((TYPE*)NULL)->MEMBER))
#define GET_CONTAINER_PTR(TYPE,MEMBER,MEMBERPTR) ((TYPE*)((unsigned int)MEMBERPTR-OFFSET(TYPE,MEMBER)))

typedef struct Triangle{//定义三角形,相当于从Shape public继承而来
Shape base;
int a,b,c;
}Triangle;

void initTriangle(Triangle* triangle,int a,int b,int c){//初始化三角形类
triangle->base.name="Triangle";
triangle->base.vptr=&vtableTriangle;//初始化虚表
triangle->a=a;
triangle->b=b;
triangle->c=c;
}

const string& getNameTriangle(Shape* shape){//得到三角形的名字
Triangle* triangle=GET_CONTAINER_PTR(Triangle,base,shape);
return triangle->base.name;
}

void drawTriangle(Shape* shape){//画出三角形
Triangle* triangle=GET_CONTAINER_PTR(Triangle,base,shape);
cout<<"a="<<triangle->a<<" b="<<triangle->b<<" c="<<triangle->c<<endl;
}

typedef struct Circle{
Shape base;
int r;
}Circle;

void initCircle(Circle* circle,int r){
circle->base.name="Circle";
circle->base.vptr=&vtableCircle;//初始化虚表
circle->r=r;
}

const string& getNameCircle(Shape* shape){
Circle* circle=GET_CONTAINER_PTR(Circle,base,shape);
return circle->base.name;
}

void drawCircle(Shape* shape){
Circle* circle=GET_CONTAINER_PTR(Circle,base,shape);
cout<<"r="<<circle->r<<endl;
}

const string& getShapeName(Shape* shape){//外层调用时使用的函数
return shape->vptr->getName(shape);
}

void drawShape(Shape* shape){//外层调用时使用的函数
shape->vptr->draw(shape);
}

int main(){
Triangle triangle;
Circle circle;
initTriangle(&triangle,3,4,5);
initCircle(&circle,10);
drawShape(&(triangle.base));
drawShape(&(circle.base));
cout<<getShapeName(&(triangle.base))<<endl;
cout<<getShapeName(&(circle.base))<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: