我有一个函数使用OpenGL绘制一个圆,我想传递一个包含x和y坐标以及半径的结构。问题是这个函数必须与3个不同的结构一起使用,所有结构都包含绘图函数不使用的坐标,半径和其他一些东西。C:为一个函数参数发送不同的结构
是否有某种方法只有一个参数为3个不同的结构(一次只发送一个参数)。
我希望我已经足够精确。 PS:函数必须是“抽象的”。
我有一个函数使用OpenGL绘制一个圆,我想传递一个包含x和y坐标以及半径的结构。问题是这个函数必须与3个不同的结构一起使用,所有结构都包含绘图函数不使用的坐标,半径和其他一些东西。C:为一个函数参数发送不同的结构
是否有某种方法只有一个参数为3个不同的结构(一次只发送一个参数)。
我希望我已经足够精确。 PS:函数必须是“抽象的”。
是的,你可以使用一个原型是这样的:
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
}
}
然而,这样做你会)需要通过另一种说法,表示正在铸造到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);
}
你是对的,枚举比一个普通的“char”更好,我的第一个方法更加肮脏^^“ – Eregrith 2012-04-18 15:42:29
同意,但是你用一个相同的数据”签名“开始单独的结构是很好的一点,类型系统和(理论上)随着时间的推移对主要功能的更改较少。 – 2012-04-18 15:47:07
+1用更聪明的方式第二个选项:这正是OO是如何在C. – mouviciel 2012-04-18 15:45:38
谢谢你们实现,我在一个结构包含一个struct的打算。 – DennisVDB 2012-04-18 16:55:04