C :为一个函数参数发送不同的结构

Den*_*VDB 4 c arguments structure function abstract

我有一个使用 OpenGL 绘制圆的函数,我想向它传递一个包含 x 和 y 坐标以及半径的结构。问题是这个相同的函数必须与 3 个不同的结构一起使用,所有结构都包含坐标、半径和绘图函数不使用的其他一些内容。

有没有办法让 3 个不同的结构只有一个参数(一次只发送一个)。

我希望我说得足够精确。

PS:函数必须是“抽象的”。

Ere*_*ith 6

是的,你可以使用这样的原型:

void foo(char type, void *data);
Run Code Online (Sandbox Code Playgroud)

使用类型告诉函数将数据用作哪个结构,就可以了。

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;
    //...
  }
  //...
}
Run Code Online (Sandbox Code Playgroud)

第二个选项,如果您想避免 switch/case,并且能够在之后添加更多结构类型,而不需要进化 foo,您可以确保所有结构都以必要的数据开头,始终以相同的顺序、相同的类型。这样你就可以从 C++ 中创建类似“接口”的东西,并使用该类型的抽象版本:

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);
Run Code Online (Sandbox Code Playgroud)

第二种方法的第二部分允许您更加灵活,分解子类型中的特定信息,使您能够将该abs部分放置在结构体 a/b/c 内的任何位置,并且更好地遵循结构体的单一用途原则(在结构体中包含坐标、半径其他内容并不总是最好的。)