试图弄清楚(实际上在Ada中),我想到了以下代码。为什么合法?

class Superclass {
public:
    virtual void Announce() {
        printf("I am the superclass\n");
    }
};

class Subclass : public Superclass {
public:
    void Announce() {
        printf("I am the subclass\n");
    }
};

int main() {
    Superclass osuper;
    Subclass osub;

    Superclass* p = &osub;
    *p = osuper;
    osub.Announce();

    return 0;
}

main()中,我创建一个Subclass实例,然后用Superclass实例物理覆盖它。然后,我成功地在被覆盖(因此已损坏)的对象上调用Subclass方法。

我不能直接分配osub = osuper,因为那没有意义,但是通过指针我似乎绕过了它。上面的代码可以正常编译,没有任何警告,但是到我调用osub.Announce()时,osub内部的内存不再包含有效的Subclass对象。

这不可能是类型安全的(或者甚至是通常安全的),但是编译器似乎非常满意。为什么?

最佳答案

在对象上使用=运算符不是无效的,并且不会覆盖任何内容,将使用默认的复制构造函数。
如果要覆盖内存中的对象,请尝试使用memcpy(p,&osub,sizeof(Superclass))。现在那将是一个覆盖:)

参见http://www.cplusplus.com/articles/y8hv0pDG/

09-27 06:46