根据我读过的各种来源,以下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();
为什么会导致未定义的行为?我看不到语言的逻辑实现,这种情况不会像预期的那样(在两个对象具有相同的运行时类型的情况下),那么为什么语言设计者选择将其定义为未定义?
答案 0 :(得分:3)
memcpy
执行浅拷贝。在一般情况下,对于不易于复制的类型,执行浅拷贝是不安全的,例如因为类型具有需要执行特殊操作的复制构造函数。
当然,您可以提供一个示例,其中使用memcpy
&#34;实际上是浅层副本&#34;但是,标准必须列出所有允许的案例,这需要了解所有有效的实施选择并评估可行的方法。
相反,标准只是说你不能这样做,这是正确的选择恕我直言。
使用memcpy
复制原始字节。使用复制构造函数来复制对象。这是一个简单,合乎逻辑的规则。
答案 1 :(得分:3)
为什么这会导致未定义的行为?
因为该语言没有指定多态性的实现方式,因此无法指定多态类型可以轻易复制。
我看不到语言的逻辑实现,而这种语言不会按预期运行
多态性可以实现为从对象地址到类型信息的映射,而不是存储在每个对象中的指针。人们可能会争论这是好还是坏,但它肯定不是不合逻辑的。
为什么语言设计师选择将其定义为未定义?
为了不限制提出更好的多态实现的可能性。你无法看到替代品并不一定意味着它们不存在。
答案 2 :(得分:2)
如果您使用memcpy,那么您将绕过对象的复制构造函数。这使您的程序处于不连贯状态(也称为未定义的行为)。