簡體   English   中英

為什么不是這種多態?

[英]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

在您的特定情況下,編譯“知道”無論是“靜態型”和“動態式” aA (因為它的類型不能“合法”的變化-你的絕招是非法的),所以沒有虛擬調度執行,但直接調用a.foo() (因此你覆蓋vptr的技巧沒有效果)。

因為你對你的memcpy任何和所有保證都是memcpy ,並且很幸運能得到任何行為。 按照你的意願使用賦值運算符!

因為 - 為什么要這樣? 編譯器發現a不是指針或引用,因此除了foo的原始實現之外不能調用任何東西。 編譯器不打擾使調用虛擬(因為這是不必要的昂貴)。

正如Oli所說,你的字節副本會引發未定義的行為。 什么都行。

memcpy(&a, &b, sizeof (b));
(&a)->foo();

這是未定義的行為 這保證僅適用於POD類型。 所以... UB是UB。 不用驚訝

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM