为什么不能用memcpy复制非POD对象?

时间:2015-03-20 13:20:59

标签: c++ undefined-behavior

根据我读过的各种来源,以下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();

为什么会导致未定义的行为?我看不到语言的逻辑实现,这种情况不会像预期的那样(在两个对象具有相同的运行时类型的情况下),那么为什么语言设计者选择将其定义为未定义?

3 个答案:

答案 0 :(得分:3)

memcpy执行浅拷贝。在一般情况下,对于不易于复制的类型,执行浅拷贝是不安全的,例如因为类型具有需要执行特殊操作的复制构造函数。

当然,您可以提供一个示例,其中使用memcpy&#34;实际上是浅层副本&#34;但是,标准必须列出所有允许的案例,这需要了解所有有效的实施选择并评估可行的方法。

相反,标准只是说你不能这样做,这是正确的选择恕我直言。

使用memcpy复制原始字节。使用复制构造函数来复制对象。这是一个简单,合乎逻辑的规则。

答案 1 :(得分:3)

  

为什么这会导致未定义的行为?

因为该语言没有指定多态性的实现方式,因此无法指定多态类型可以轻易复制。

  

我看不到语言的逻辑实现,而这种语言不会按预期运行

多态性可以实现为从对象地址到类型信息的映射,而不是存储在每个对象中的指针。人们可能会争论这是好还是坏,但它肯定不是不合逻辑的。

  

为什么语言设计师选择将其定义为未定义?

为了不限制提出更好的多态实现的可能性。你无法看到替代品并不一定意味着它们不存在。

答案 2 :(得分:2)

如果您使用memcpy,那么您将绕过对象的复制构造函数。这使您的程序处于不连贯状态(也称为未定义的行为)。