分配给成员的工会

时间:2010-02-05 18:54:34

标签: c++ unions

假设我有一个有工会成员的班级:

class ClassX {
public:
  union {
    StructA * A;
    StructB * B;
    };
  }

如果我将指针x1和x2指向不同的ClassX对象,请执行以下操作:

x1->A = x2->A;

具有与此相同的效果:

x1->B = x2->B;

?感谢。

5 个答案:

答案 0 :(得分:5)

对于大多数实际用途,在大多数实现中,这两个语句会产生相同的效果,但不能保证。如果从联合中读取的成员不是写入联合的最后一个成员,则程序的行为是未定义的。

因为union的两个成员都是指向结构的指针,所以很可能它们占用相同的大小并具有类似的表示,因此分配任何一个union成员很可能正确地分配另一个union成员,如果那是实际存储在源中的那个联合。

答案 1 :(得分:2)

您期望得到什么样的答案?

正式而迂腐的?如果是这样,那么这个问题根本就没有答案。 C ++语言确实为您提供了比较这两个作业的效果的正式机会。如果您分配了ClassX::A,则只能阅读ClassX::A而不是ClassX::B。如果您分配了ClassX::B,则只能阅读ClassX::B而不是ClassX::A。换句话说,即使关心效果是否相同,也没有任何有意义的理由。语言根本不允许你关心它。如果您的代码以某种方式依赖于它,那么就其正式的C ++而言,它的行为是未定义的。

至于对这个问题的现实生活实际答案......是的,在语言的任何合理实施中效果都应该相同。

答案 2 :(得分:1)

C++1x Standard Draft, Section 9.5.1

  

在联盟中,最多只有一个数据   会员可以随时活跃,   也就是说,最多只有一个的价值   数据成员可以存储在   工会在任何时候。 [注意:一个特别的   保证是为了简化   工会的使用:如果是POD工会   包含几个POD结构   共享一个共同的初始序列   (class.mem),如果是这个的对象   POD-union类型包含其中之一   POD结构,允许   检查共同的初始序列   任何POD结构成员;看到   class.mem。 ]

请注意特殊保证。

答案 3 :(得分:0)

除非StructA和StructB具有相同的大小,否则它们的效果不同。您发布的第一行将x2->A占用的所有内存复制到x1->A,而第二行则为B执行相同的操作。 AB占用了重叠的内存区域,但它们的大小可能不同,在这种情况下,这两个语句不相同。

答案 4 :(得分:0)

操作应该相同。但是,如果你为这两种指针类型中的任何一种重载赋值运算符,情况可能就不是这样了。