为什么不能用memcpy复制非POD对象?
Why can't non-POD objects be copied with memcpy?
根据我阅读的各种来源,以下C++代码调用未定义的行为:
class A {
public:
virtual void method () {
std::cout << "Hello" << std::endl;
}
};
...
A *a, *b;
// obtain 2 Instances from somewhere, then...
memcpy (a, b, sizeof(A));
a->method();
为什么这会导致未定义的行为?我看不到该语言的逻辑实现会不按预期运行(在两个对象都具有相同运行时类型的情况下),那么为什么语言设计者选择不定义它呢?
memcpy
执行浅层复制。在一般情况下,对于不可复制的类型,执行浅层复制是不安全的,例如,因为该类型有一个需要执行特殊操作的复制构造函数。
当然,你可以举一个例子,使用memcpy
的浅拷贝实际上"有效",但标准必须列出所有允许的情况,这需要知道所有有效的实现选择,并评估什么是有效的。
相反,标准只是说你不能这样做,这是IMHO的正确选择。
使用memcpy
复制原始字节。使用复制构造函数来复制对象。这是一条简单、合乎逻辑的规则。
为什么这会导致未定义的行为?
因为该语言没有指定多态性是如何实现的,因此不能指定多态类型是可复制的。
我看不出该语言的逻辑实现不会像预期的那样运行
多态性可以实现为从对象地址到类型信息的映射,而不是存储在每个对象中的指针。人们可能会争论这是好是坏,但这肯定不是不合逻辑的。
为什么语言设计者选择不定义这个?
这样就不会限制多态性更好实现的可能性。你看不到替代品并不一定意味着它们不存在。
如果使用memcpy,则绕过对象的复制构造函数。这会使您的程序处于不连贯的状态(也称为未定义的行为)。
相关文章:
- Qt5 远程对象 + 自定义类型,但不在 POD 中
- C++定义构造函数使对象成为非 POD
- 具有非 POD 对象的 GLib 异步队列
- 泛型运算符== 用于非 pod 对象
- 初始化新对象时C++默认构造函数和 POD 问题
- 通过指向其基的指针删除 POD 对象是否安全
- 为什么不能用memcpy复制非POD对象?
- 从数据成员(一次性嵌套类)中获取非 POD 对象的地址
- 使用static_cast铸造POD对象
- POD 类对象初始化是否需要构造函数
- 使用 memcpy 移动非 POD C++对象是否总是调用未定义行为
- C++不能传递非 POD 类型的对象
- 函数作用域的静态非 Pod 对象初始化
- 在共享库中全局声明的非pod对象的语义是什么?
- 从动态创建的数组构造pod对象时,是否推荐使用placement new ?
- 对于非pod对象,xvalue和右值在允许使用或行为方面的差异示例是什么?
- 为什么常量 POD 对象中的字段本身不是常量?
- 如何比较POD类型的对象
- C++标准是否允许对具有常量成员的 POD 对象进行零初始化
- 具有公共链接的非 POD 对象:应该发生什么?