假设我有一个班级,里面有工会成员:
class ClassX {
public:
union {
StructA * A;
StructB * B;
};
}
如果我有指向不同 ClassX 对象的指针 x1 和 x2,请执行以下操作:
x1->A = x2->A;
与此具有相同的效果:
x1->B = x2->B;
? 谢谢。
对于大多数实际目的,在大多数实现中,这两个语句将具有相同的效果,但不能保证。如果您从联合中读取的成员不是写入联合的最后一个成员,则程序的行为是未定义的。
因为联合的两个成员都是指向结构的指针,所以它们很可能占用相同的大小并且具有类似的表示,因此如果这是实际存储在源联合中的内容,那么分配任一联合成员很可能会正确分配另一个联合成员。
你期待什么样的答案?
一个正式的和迂腐的?如果是这样,那么这个问题根本就没有答案。C++ 语言确实为您提供了任何正式的机会来比较这两个分配的效果。如果你分配ClassX::A
了,你只能读ClassX::A
而不能ClassX::B
。如果你分配ClassX::B
了,你只能读ClassX::B
而不能ClassX::A
。换句话说,没有有意义的理由去关心效果是否相同。语言根本不允许你关心它。如果您的代码以某种方式依赖它,那么就正式的 C++ 而言,它的行为是未定义的。
至于该问题的实际答案......是的,在任何合理的语言实现中效果应该是相同的。
在一个联合中,任何时候最多有一个数据成员处于活动状态,即任何时候最多可以有一个数据成员的值存储在一个联合中。[注意:为了简化联合的使用,我们做了一个特别的保证:如果一个 POD-联合包含多个共享一个公共初始序列(class.mem)的 POD-结构,并且如果这个 POD-联合类型的对象包含其中一个 POD 结构,允许检查任何 POD 结构成员的公共初始序列;见class.mem。]
请注意特别保证。
除非 StructA 和 StructB 具有相同的大小,否则它们不会产生相同的效果。x2->A
您发布的第一行复制了into占用的所有内存x1->A
,而第二行对B
. A
并B
占用内存的重叠区域,但它们可能是不同的大小,在这种情况下,这两个语句是不等价的。
操作应该相同。但是,如果您为这两种指针类型中的任何一种重载了赋值运算符,则情况可能并非如此。