学习笔记
《深入理解C指针》
http://www.ituring.com.cn/book/1147
8.4.2 C中的多态
内存示意图
内存示意图函数指针也是指针,既然是指针,那么同一台机器同一个编译器,大小就是固定的;
我的机器上,指针大小是8字节,int
大小是4字节,那么一个Shape类型刚好是8*5+4*2=48
字节
运行结果
指针变量 sptr 的值 函数 setX 的入口地址 C的多态完整源码
#include <stdio.h>
#include <stdlib.h>
typedef void (*fptrSet)(void*,int);
typedef int (*fptrGet)(void*);
typedef void (*fptrDisplay)();
typedef struct _functions {
// 函数
fptrSet setX;
fptrGet getX;
fptrSet setY;
fptrGet getY;
fptrDisplay display;
} vFunctions;
typedef struct _shape {
vFunctions functions;
// 基类变量
int x;
int y;
} Shape;
void shapeDisplay(Shape *shape) { printf("Shape\n");}
void shapeSetX(Shape *shape, int x) {shape->x = x;}
void shapeSetY(Shape *shape, int y) {shape->y = y;}
int shapeGetX(Shape *shape) { return shape->x;}
int shapeGetY(Shape *shape) { return shape->y;}
Shape* getShapeInstance() {
Shape *shape = (Shape*)malloc(sizeof(Shape));
shape->functions.display = (fptrDisplay)shapeDisplay;
shape->functions.setX = (fptrSet)shapeSetX;
shape->functions.getX = (fptrGet)shapeGetX;
shape->functions.setY = (fptrSet)shapeSetY;
shape->functions.getY = (fptrGet)shapeGetY;
shape->x = 100;
shape->y = 100;
return shape;
}
typedef struct _rectangle {
Shape base;
int width;
int height;
} Rectangle;
void rectangleSetX(Rectangle *rectangle, int x) { rectangle->base.x = x;}
void rectangleSetY(Rectangle *rectangle, int y) { rectangle->base.y;}
int rectangleGetX(Rectangle *rectangle) { return rectangle->base.x;}
int rectangleGetY(Rectangle *rectangle) { return rectangle->base.y;}
void rectangleDisplay() { printf("Rectangle\n");}
Rectangle* getRectangleInstance() {
Rectangle *rectangle = (Rectangle*)malloc(sizeof(Rectangle));
rectangle->base.functions.display = (fptrDisplay)rectangleDisplay;
rectangle->base.functions.setX = (fptrSet)rectangleSetX;
rectangle->base.functions.getX = (fptrGet)rectangleGetX;
rectangle->base.functions.setY = (fptrSet)rectangleSetY;
rectangle->base.functions.getY = (fptrGet)rectangleGetY;
rectangle->base.x = 200;
rectangle->base.y = 200;
rectangle->height = 300;
rectangle->width = 500;
return rectangle;
}
int main()
{
// Shape 的用例
printf("----Test Shape:----\n");
Shape *sptr = getShapeInstance();
sptr->functions.setX(sptr,35);
sptr->functions.display();
printf("%d\n", sptr->functions.getX(sptr));
// 输出测试
/*
printf("&sptr:0x%p sptr:0x%p *sptr:0x%p\n", &sptr, sptr, *sptr);
printf("&shapeSetX:0x%p shapeSetX:0x%p\n", &shapeSetX, shapeSetX);
printf("&shapeGetX:0x%p shapeGetX:0x%p\n", &shapeGetX, shapeGetX);
printf("&shapeSetY:0x%p shapeSetY:0x%p\n", &shapeSetY, shapeSetY);
printf("&shapeGetY:0x%p shapeGetY:0x%p\n", &shapeGetY, shapeGetY);
printf("&sptr->functions:0x%p \n",&(sptr->functions));
printf("sptr->functions:0x%p \n",sptr->functions);
printf("&sptr->functions.setX:0x%p sptr->functions.setX:0x%p shapeSetX:0x%p\n"
, &(sptr->functions.setX), sptr->functions.setX, shapeSetX);
printf("&sptr->functions.getX:0x%p sptr->functions.getX:0x%p shapeGetX:0x%p\n"
, &(sptr->functions.getX), sptr->functions.getX, shapeGetX);
printf("&sptr->functions.setY:0x%p sptr->functions.setY:0x%p shapeSetY:0x%p\n"
, &(sptr->functions.setY), sptr->functions.setY, shapeSetY);
printf("&sptr->functions.getY:0x%p sptr->functions.getY:0x%p shapeGetY:0x%p\n"
, &(sptr->functions.getY), sptr->functions.getY, shapeGetY);
printf("&sptr->functions.display:0x%p sptr->functions.display:0x%p shapeDisplay:0x%p\n"
, &(sptr->functions.display), sptr->functions.display, shapeDisplay);
printf("&sptr->x:0x%p sptr->x:%d\n", &(sptr->x), sptr->x);
printf("&sptr->y:0x%p sptr->y:%d\n", &(sptr->y), sptr->y);
*/
// Rectangle 用例
printf("----Test Rectangle:----\n");
Rectangle *rptr = getRectangleInstance();
rptr->base.functions.setX(rptr,35);
rptr->base.functions.display();
printf("%d\n", rptr->base.functions.getX(rptr));
// 测试多态
printf("----Test Polymorphism:----\n");
Shape *shapes[3];
shapes[0] = getShapeInstance();
shapes[0]->functions.setX(shapes[0],1);
shapes[1] = (Shape *)getRectangleInstance();
shapes[1]->functions.setX(shapes[1],2);
shapes[2] = getShapeInstance();
shapes[2]->functions.setX(shapes[2],3);
for(int i=0; i<3; i++) {
shapes[i]->functions.display();
printf("%d\n", shapes[i]->functions.getX(shapes[i]));
}
return 0;
}
网友评论