[C指针]C的多态

2019-04-21  本文已影响0人  AkuRinbu

学习笔记

《深入理解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;
}

上一篇下一篇

猜你喜欢

热点阅读