能否用std::memcpy拷贝成员序列相同的不同C++类对象?
问题
给定两个C++类:
class a { int m1; float m2; char m3[8]; }; class b { int n1; float n2; char n3[8]; };
能否使用std::memcpy将a类型对象拷贝到b类型对象,且正确获取my_b成员的值?对应的代码如下:
a my_a; // 假设已为my_a的成员赋值。 b my_b; std::memcpy(&my_b, &my_a, sizeof(a));
同时需要解答以下问题:
- 若上述操作可行,该操作在通用场景下如何生效?
- 成员序列相同的不同类型中,平凡可拷贝类型是否为可使用
std::memcpy的最大集合? - 如下条件是否足以验证该跨类型拷贝操作的有效性?
std::is_layout_compatible_v<T, U> && std::is_trivially_copyable_v<T> && std::is_trivially_copyable_v<U> == true
回答
示例代码的可行性
可以这么操作,并且能正确获取my_b的成员值。这两个类都属于标准布局类型,成员的类型、顺序、大小完全一致,内存布局完全匹配,std::memcpy会直接复制内存中的二进制数据,my_b的每个成员会对应拿到my_a成员的二进制值,因此能正常读取。
通用场景的生效逻辑
跨类型std::memcpy拷贝后要能正确访问成员,核心满足两个条件:
- 内存布局兼容:两个类型的成员在内存中的偏移、大小、类型完全对应,拷贝后的二进制数据能被目标类型正确解析;
- 平凡可拷贝:类型没有自定义拷贝构造/赋值运算符、非平凡析构函数,内存拷贝仅做二进制数据复制,不会触发额外逻辑,保证对象状态完整。
平凡可拷贝是否为最大集合
不是。从C++标准定义来看,只要两个类型布局兼容,即使不是平凡可拷贝,也能执行std::memcpy内存拷贝,但此时访问目标对象成员属于未定义行为——非平凡可拷贝类型可能包含虚表指针、资源句柄等内部状态,直接内存拷贝会破坏这些状态,导致后续访问出错。
而平凡可拷贝类型是唯一能保证内存拷贝后对象处于有效状态的类型集合,所以它是工程中跨类型memcpy的安全边界,但并非“能执行拷贝”的最大集合,只是唯一安全的集合。
给定条件的有效性
是的。std::is_layout_compatible_v<T, U>确保两个类型的内存布局可互相解析,std::is_trivially_copyable_v<T>和std::is_trivially_copyable_v<U>确保内存拷贝不会触发非平凡操作,也不会让对象处于无效状态。同时满足这三个条件时,跨类型std::memcpy拷贝并访问成员是标准规定的合法行为,不存在未定义行为。
内容的提问来源于stack exchange,提问作者sayurc
相关产品推荐
相关产品推荐

