下面是我声明的类型:
(我也声明了t_sphere
、t_cylinder
和t_triangle
)
typedef struct s_intersection{
double t1;
double t2;
int id;
union {
t_sphere sph;
t_cylinder cyl;
t_triangle tri;
} u;
} t_intersection;
当我在某些代码中使用交集结构时,是否有一种方便的方法来引用联合体中的成员?
例如,假设我想写一个函数,根据它所包含的geometric_figure的类型,它的行为会有所不同,我必须这样做吗?
if (geometric_figure_id == SPHERE_ID)
// I know I will have to refer to p->u with p->u.sph...
else if(geometric_figure_id == CYLINDER_ID)
// I know I will have to refer to p->u with p->u.cyl...
else if (geometric_figure_id == TRIANGLE_ID)
// I know I will have to refer to p->u with p->u.tri...
如果我有10个不同的geometric_figures类型在我的union里面呢?这感觉很沉重。
你有更优雅的解决方案吗?
2条答案
按热度按时间t40tm48m1#
假设我想写一个函数,根据它所包含的geometric_figure的类型,它的行为会有所不同,我必须这样做吗?
听起来其他语言对运行时多态函数调度的支持可能是你的问题的一部分,如果是这样,那么重要的是要认识到你在这里调度的不是任何对象的 * 类型 *,就像你通常在C++或Java中那样,而是一个整数的 * 值 。
如果您希望对一个整数的不同运行时值遵循不同的控制路径,那么除了编写一个流控制语句(通常为
if
/else if
/else
或switch
)来适当地指导控制之外,没有其他选择。现在,如果你 * 是 * 在类型上调度,那么C确实提供了类型泛型表达式。在大多数情况下,这些表达式只在宏内部使用是有意义的:
在宏以外的上下文中,您已经知道了所涉及的类型,因此类型泛型表达式不会为您带来任何值得拥有的东西。
取决于您要应用多少宏魔法,有很多方法可以避免手工写出长的
if
/else if
/else
语句或长的switch
语句。类型通用宏可能会在类似的事情中扮演一个角色。但是这样的操作过程很难很好地实现。我们更有可能以复杂宏堆栈的混乱维护噩梦而告终,而不是得到可以与手动编写的switch
语句相媲美的东西。oalqel3c2#
你有更优雅的解决方案吗?
说"更优雅"使它基于观点,所以我宁愿称之为替代解决方案,而不是"更优雅"的解决方案。
为了避免许多嵌套的if语句(或者一个大的switch语句),你可以添加一个函数指针,所以当你创建一个
t_intersection
的示例时,你也可以设置函数指针指向t_intersection
的特定子类型所需要的函数。下面是一个基于OP代码的示例,为了使其更简单,做了一些修改。
输出: