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

来源:互联网 发布:php销售管理系统 编辑:程序博客网 时间:2024/05/16 02:49
#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;}

0 0
原创粉丝点击