并非所有类型的成员都初始化时,可以复制普通类型的类吗? [英] Can a trivial type class be copied when not all its members are initialized?
问题描述
(我刚刚意识到我首先需要通过复制联合来解决一个更基本的问题:
(I just realized I first need to solve a much more basic issue with copying unions: When a union object is copied, is a member subobject created?. Please see that other question first.)
类的隐式生成的复制操作(构造函数和赋值)执行成员复制(初始化或赋值). (对于普通类型,它们是相同的.)
The implicitly generated copy operations (constructor and assignment) of a class perform member by member copy (initialization or assignment). (For a trivial type these are the same.)
由于某些未初始化成员的类是非法的,因此无法复制该类.
So a class with some members not initialized cannot be copied, as accessing uninitialized objects is illegal.
struct C {
int m1, m2;
};
void f() {
C c1, c2;
c1.m1 = 1;
c2 = c1; // not initialized
}
但是,即使工会包含类成员,但其中的某些成员未初始化(因为……根据定义,不是工会的两个成员都被初始化),也可以始终复制该工会.
But a union can always be copied, even if it contains class members, some of which aren't initialized (because... by definition not two members of a unions are initialized).
这是否意味着复制具有未初始化成员的类的并集是合法的:
Does that mean that copying a union of a class with uninitialized members is legal:
union U {
C m;
};
void g() {
U u1, u2;
u1.m.m1 = 1;
u2 = u1;
}
,如果是这样,是否可以通过强制转换为此类联合来复制类?
and if so, can classes be copied by casting to such union?
void f2() {
C c1, c2;
c1.m1 = 1;
(U&)c2 = (U&)c1; // not initialized?
}
推荐答案
是的,您可以通过定义为复制对象表示形式的默认复制/移动赋值运算符来复制具有未初始化(间接)成员的联合. (您也可以编写自己的使用std::memcpy
的运算符.如果默认的运算符未建立正确的活动成员,显然这是措辞上的缺陷,并且std::memcpy
也应该这样做.)
Yes, you can copy the union with the uninitialized (indirect) member—via the default copy/move assignment operator that is defined to copy the object representation. (You could also write your own operator that used std::memcpy
. It is obviously a wording defect if the defaulted operator doesn’t establish the correct active member, and is std::memcpy
should do so as well.)
但是,您不能将强制转换为普通类对象的更安全副本.根据特殊规则,对赋值运算符的调用具有未定义的行为必需,因为它不涉及对任何(标量)对象的访问.即使通过reinterpret_cast
(!),您自己的基于std::memcpy
的实现也可以,但这不具有新闻价值-通过unsigned char
(可能是char
)和std::byte
读取/复制不确定的值是始终允许).
However, you cannot use cast-to-union as a safer copy for normal class objects; the call to the assignment operator has undefined behavior per a special rule needed because it doesn’t involve an access to any (scalar) object. Your own std::memcpy
-based implementation would be fine, even via reinterpret_cast
(!), but that’s not newsworthy—reading/copying indeterminate values via unsigned char
(and perhaps char
) and std::byte
is always allowed).
这篇关于并非所有类型的成员都初始化时,可以复制普通类型的类吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!