Is it possible to do inheritance from an abstract/base struct or simulate something along those lines in C?

前端 未结 3 1778
梦谈多话
梦谈多话 2020-12-21 01:07

I am currently working with a C program that uses structs composed of xyz coordinates, but sometimes these coordinate may refer to vectors (Force/velocity type, not the data

3条回答
  •  情话喂你
    2020-12-21 01:47

    I've done this sort of thing before. I embed a copy of the base type at the front of the derived type struct. This more closely mimics what c++ might do. Here are two methods I've used.


    Using simple type:

    #define XYZDEF \
        int type; \
        float x; \
        float y; \
        float z
    
    // base type
    struct xyzdata {
        XYZDEF;
    };
    
    // derived type 1
    struct vector {
        XYZDEF;
        int vector_info;
        ...
    };
    
    // derived type 2
    struct position {
        XYZDEF;
        int position_info;
        ...
    };
    
    #define BASEOF(_ptr) \
        ((struct xyzdata *) (_ptr))
    
    // vector_rotate -- rotate a vector
    void
    vector_rotate(vector *ptr)
    {
    }
    
    // position_rotate -- rotate a position
    void
    position_rotate(position *ptr)
    {
    }
    
    // xyzrotate -- rotate
    void
    xyzrotate(xyzdata *ptr)
    {
    
        switch (ptr->type) {
        case TYPE_POSITION:
            vector_rotate((vector *) ptr);
            break;
        case TYPE_VECTOR:
            position_rotate((position *) ptr);
            break;
        }
    }
    

    Using a virtual function table pointer:

    #define XYZDEF \
        int type; \
        vtbl *vtbl; \
        float x; \
        float y; \
        float z
    
    // forward definitions
    struct xyzdata;
    struct vector;
    struct position;
    
    // virtual function table
    struct vtbl {
        void (*rotate)(struct xyzdata *);
    };
    
    // base type
    struct xyzdata {
        XYZDEF;
    };
    
    // derived type 1
    struct vector {
        XYZDEF;
        int vector_info;
        ...
    };
    
    // derived type 2
    struct position {
        XYZDEF;
        int position_info;
        ...
    };
    
    #define BASEOF(_ptr) \
        ((struct xyzdata *) (_ptr))
    
    // vector_rotate -- rotate a vector
    void
    vector_rotate(struct xyzdata *ptr)
    {
        struct vector *vec = (void *) ptr;
        ...
    }
    
    // position_rotate -- rotate a position
    void
    position_rotate(struct xyzdata *ptr)
    {
        struct position *pos = (void *) ptr;
        ...
    }
    
    // xyzrotate -- rotate
    void
    xyzrotate(xyzdata *ptr)
    {
    
        ptr->vtbl->rotate(ptr);
    }
    

提交回复
热议问题