C : send different structures for one function argument

后端 未结 2 546
日久生厌
日久生厌 2021-01-13 19:13

I have a function that draws a circle using OpenGL, I would like to pass it a structure containing the x and y coordinates and the radius. The problem is this same function

2条回答
  •  臣服心动
    2021-01-13 19:25

    Yes you can use a prototype like this:

    void foo(char type, void *data);
    

    Use the type to tell the function which struct to use the data as, and you're good.

    struct c *prepareStructC(void);
    //...
    struct c *toto = prepareStructC();
    foo('c', toto);
    //...
    void foo(char type, void *data)
    {
      int x, y;
      switch (type)
      {
        case 'c':
          x = ((struct c*)data)->x;
          y = ((struct c*)data)->y;
          break;
        //...
      }
      //...
    }
    

    Second option, if you want to avoid a switch/case, and be able to add more struct types afterwards, without evolving foo, you can make sure all your structs begin with the necessary data, always in the same order, with the same type. This way you can make something like an "interface" from C++, and use abstract versions of the type:

    struct abstract
    {
      int x;
      int y;
      int radius;
    }
    
    struct a
    {
      struct abstract abs;
      //... other data ...
    }
    struct b
    {
      struct abstract abs;
      //... other data ...
    }
    struct c
    {
      struct abstract abs;
      //... other data ...
    }
    
    //Two choices : either you have:
    void foo(void *data)
    {
      int x,y,r;
      x = ((struct abstract*)data)->x;
      y = ((struct abstract*)data)->y;
      r = ((struct abstract*)data)->radius;
      //...
    }
    
    //OR Smarter way:
    void foo2(struct abstract *data)
    {
      int x,y,r;
      x = data->x;
      y = data->y;
      r = data->radius;
    }
    //Calling foo2 with:
    struct a *sa = prepareStructA();
    struct b *sb = prepareStructB();
    struct c *sc = prepareStructC();
    foo2(sa->abs);
    foo2(sb->abs);
    foo2(sc->abs);
    

    The second part of the second method allows you more flexibility, breaking down specific information in a subtype, enables you to put the abs part anywhere inside the struct a/b/c, and is better in the principle of a single purpose for a struct (Having coordinates and radius and other things inside a struct is not always the best.)

提交回复
热议问题