问题
(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?
}
回答1:
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.)
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).
来源:https://stackoverflow.com/questions/59231856/can-a-trivial-type-class-be-copied-when-not-all-its-members-are-initialized