美文网首页
[C指针]C的多态

[C指针]C的多态

作者: AkuRinbu | 来源:发表于2019-04-21 15:44 被阅读0次

    学习笔记

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

    相关文章

      网友评论

          本文标题:[C指针]C的多态

          本文链接:https://www.haomeiwen.com/subject/emulgqtx.html