C与联盟的继承

Bra*_*eel 8 c inheritance unions

我正在阅读有关如何在C中实现某些面向对象功能的内容,并且它已被证明非常有用.具体来说,我一直在玩弄继承的想法.这是一个例子:

typedef struct Circle{
     int rad, x, y;
     //Other things...
} Circle;

typedef struct Entity{
    Circle body;
    //Entity-specific items...
} Entity;
Run Code Online (Sandbox Code Playgroud)

这很简单,但它允许偷偷摸摸的东西.指向实体的指针也是指向Circle的指针,因为实体的第一个元素始终是Circle.有了这个想法,我们可以构造以下功能:

int checkCircleCollision(Circle* one, Circle* two);
Run Code Online (Sandbox Code Playgroud)

并称之为:

Entity* myentity = createEntity(/* Things specific to my entity */);
Entity* myotherentity = createEntity(/* Different things */);
//Did they collide?
if (checkCircleCollision(myentity, myotherentity)){
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

这太棒了,但我遇到了一个问题.如果我想让我的某些实体成为矩形怎么办?我有一个解决方案,但无论编译器如何,我都希望确认它始终有效.我对工会的了解非常有限.

//Circle defined as above...
typedef struct Rectangle{
    int x, y, w, h;
    //Other things...
} Rectangle;

int checkRectangleCollision(Rectangle* one, Rectangle* two);
int checkRectangleCircleCollision(Rectangle* rect, Circle* circ);

typedef struct Entity{
     union{
         Rectangle rect;
         Circle circ;
     } shape;
     int type;
     //Entity things...
}
Run Code Online (Sandbox Code Playgroud)

现在可以完全安全地假设a的第一个元素Entity是a Rectangle或a Circle,具体取决于它的初始化吗?此外,它可以用于上述三种功能中的任何一种吗?标准相关报价的奖励积分.要非常清楚,我想这样做:

Entity* rectentity = createEntity(RECTANGLE, /* width/height/etc */);
Entity* circentity = createEntity(CIRCLE, /* rad/x/y/etc */ );
if (checkRectangleCircleCollision(rectentity, circentity)){
     /* ... */
}
Run Code Online (Sandbox Code Playgroud)

小智 4

现在可以完全安全地假设实体的第一个元素是矩形或圆形,具体取决于其初始化吗?

是的。

标准中的相关引用可加分。

  • “联合类型描述了一组重叠的非空成员对象,每个成员对象都有一个可选指定的名称和可能不同的类型。” (C99,6.2.5.20)

  • “指向联合对象的指针,经过适当转换后,指向其每个成员(或者如果成员是位字段,则指向它所在的单元),反之亦然。” (6.7.2.1.14)