[英]Why isn't this polymorphic?
#include <cstdio>
#include <cstring>
class A
{
public:
virtual void foo()
{
puts("A");
}
};
class B : public A
{
public:
void foo()
{
puts("B");
}
};
int main()
{
A a;
B b;
memcpy(&a, &b, sizeof (b));
(&a)->foo();
}
在非POD類型上執行原始內存操作(例如memcpy
)會調用未定義的行為 。 你不應該這樣做!
你不應該像那樣混淆非POD類型。 特別是,C ++標准說memcpy
荷蘭國際集團在不確定的行為,它在你的情況,顯示了繼續看到非莢結果a
為類型的A
。
在您的特定情況下,編譯“知道”無論是“靜態型”和“動態式” a
是A
(因為它的類型不能“合法”的變化-你的絕招是非法的),所以沒有虛擬調度執行,但直接調用a.foo()
(因此你覆蓋vptr的技巧沒有效果)。
因為你對你的memcpy
任何和所有保證都是memcpy
,並且很幸運能得到任何行為。 按照你的意願使用賦值運算符!
因為 - 為什么要這樣? 編譯器發現a
不是指針或引用,因此除了foo
的原始實現之外不能調用任何東西。 編譯器不打擾使調用虛擬(因為這是不必要的昂貴)。
正如Oli所說,你的字節副本會引發未定義的行為。 什么都行。
A a;
B b;
memcpy(&a, &b, sizeof (b));
如果A有成員,您將在此代碼中具有訪問沖突。 正確的方法是下一個:
A a;
B b;
A *c = &a;
c->foo(); //A::foo()
c = &b;
c->foo(); //B::foo()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.