C:为一个函数参数发送不同的结构
我有一个使用OpenGL绘制圆的函数,我想传递一个包含x和y坐标以及半径的结构。 问题是这个相同的函数必须与3个不同的结构一起使用,所有结构都包含坐标,半径和绘制函数不使用的其他一些东西。
有没有办法只为3个不同的结构有一个参数(一次只发送一个)。
我希望我已经足够精确了。
PS:function必须是“抽象的”。
是的你可以使用这样的原型:
void foo(char type, void *data);
使用类型告诉函数哪个结构使用数据,你很好。
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; //... } //... }
第二个选项,如果你想避免一个开关/案例,并且能够在不改进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);
第二种方法的第二部分允许您更灵活,分解子类型中的特定信息,使您能够将abs
部分放在struct a / b / c中的任何位置,并且在结构的单一用途原则中更好(在结构中具有坐标和半径以及其他内容并不总是最好的。)
仅当函数接受void*
作为参数时,然后在取消引用它以访问其中的数据之前,将void*
转换为函数中的正确指针类型。
typedef enum { type1, type2, type3 } datatype; void foo(void* data, datatype type) { switch(type) { case type1: // do something with data by casting it to the proper type break; // ... other cases here } }
但是,通过这样做你将a)需要传递另一个参数,表明原始类型在传递之前被转换为void*
,并且b)你放弃了类型系统,这几乎不是一个好主意,应该始终避免。
如果你采用这种方法, 强烈建议在内部调用函数(带有void*
)之前创建三个采用正确类型的“包装”函数。 永远不要直接调用void*
函数,这是一个严格的约定; 只调用包装器。 通过这种方式,您仍然可以使用类型系统来帮助解决编译错误。
void bar1(someStruct* data) { foo((void*) data, type1); } void bar2(someOtherStruct* data) { foo((void*) data, type2); } void bar3(yetAnotherStruct* data) { foo((void*) data, type3); }