1

(我刚刚意识到我首先需要解决复制联合的一个更基本的问题:复制联合对象时,是否创建了成员子对象?请先查看其他问题。)

类的隐式生成的复制操作(构造函数和赋值)执行逐个成员的复制(初始化或赋值)。(对于普通类型,这些是相同的。)

因此,无法复制具有某些未初始化成员的类,因为访问未初始化的对象是非法的。

struct C {
  int m1, m2;
};

void f() {
  C c1, c2;

  c1.m1 = 1;
  c2 = c1; // not initialized
}

但是一个联合总是可以被复制,即使它包含类成员,其中一些没有初始化(因为......根据定义,联合的两个成员没有被初始化)。

这是否意味着复制具有未初始化成员的类的联合是合法的:

union U {
  C m;
};

void g() {
  U u1, u2;
  u1.m.m1 = 1;
  u2 = u1;
}

如果是这样,可以通过强制转换到这样的联合来复制类吗?

void f2() {
  C c1, c2;

  c1.m1 = 1;
  (U&)c2 = (U&)c1; // not initialized?
}
4

1 回答 1

2

是的,您可以通过定义为复制对象表示的默认复制/移动赋值运算符来复制具有未初始化(间接)成员的联合。(您也可以编写自己的使用std::memcpy.std::memcpy

但是,您不能将 cast-to-union 用作普通类对象的更安全的副本;根据需要的特殊规则,对赋值运算符的调用具有未定义的行为,因为它不涉及对任何(标量)对象的访问。即使通过 (!),您自己std::memcpy的基于实现也可以reinterpret_cast,但这并不具有新闻价值——通过unsigned char(并且可能char)读取/复制不确定的值,并且std::byte总是被允许的)。

于 2019-12-08T06:35:19.797 回答