问题
According to various sources I've read, the following C++ code invokes undefined behaviour:
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();
Why does this cause undefined behaviour? I can see no logical implementation of the language where this would not behave as expected (in the case where both objects have the same run-time type), so why did the language designers choose to make this undefined?
回答1:
memcpy
does a shallow copy. In the general case, doing a shallow copy is not safe for types that are not trivially-copyable, for example because the type has a copy constructor that needs to do something special.
Of course you can come up with an example where actually a shallow copy using memcpy
"works" but then the standard would have to list all the cases that are allowed, and that would require knowing all the valid implementation choices and assessing what would work.
Instead the standard just says you can't do it, which is the right choice IMHO.
Use memcpy
for copying raw bytes. Use a copy constructor for copying objects. It's a simple, logical rule.
回答2:
Why does this cause undefined behaviour?
Because the language doesn't specify how polymorphism is implemented, and therefore can't specify that polymorphic types be trivially copyable.
I can see no logical implementation of the language where this would not behave as expected
Polymorphism could be implemented as a map from object addresses to type information, rather than a pointer stored in each object. One might debate whether that would be better or worse, but it's certainly not illogical.
why did the language designers choose to make this undefined?
So as not to constrain the possibility of coming up with better implementations of polymorphism. Your inability to see alternatives doesn't necessarily mean that they don't exist.
回答3:
If you use memcpy then you are bypassing the object's copy constructors. This leaves your program in an incoherent state (aka undefined behavior).
来源:https://stackoverflow.com/questions/29167512/why-cant-non-pod-objects-be-copied-with-memcpy