C++继承在堆栈上不起作用

C++ inheritance not working on stack?

本文关键字:不起作用 堆栈 继承 C++      更新时间:2023-10-16

这是一个大得多的代码的缩小问题。我知道 C.a 应该在堆上,但我想避免在代码中的任何地方将"."更改为"->"。有没有办法绕过这个错误?(编译器是 g++ 4.6.1(我认为这是一个错误,因为 c++ 允许它但行为不恰当......

#include <iostream>
using namespace std;
class AA {
public:
    virtual void foo() {
        cout << "AA!n";
    };
};
class AB : public AA {
public:
    AB() : AA() { cout << "construct AB!n"; }
    void foo() {
        cout << "AB!n";
    }
};
class C {
public:
    AA a;
    void xchg() {
        a.~AA();
        new (&a) AB();  // everything works here except virtuals
    }
};
int main() {
    C c;
    c.a.foo(); // -> AA
    c.xchg();
    c.a.foo(); // -> AA :(
    AA *aa = new AB();
    aa->foo(); // -> AB (virtual works)
    return 0;
};

唯一的错误是你的代码。 您正在调用未定义的行为(实际上以几种不同的方式(。

该标准不需要对此进行诊断,编译器没有责任确保您不会做任何愚蠢的事情。

new (&a) AB();  // everything works here except virtuals

这实际上不起作用:这里的行为是未定义的。 a 是类型 AA 的对象。 不能在其位置构造 AB 类型的对象。 唯一允许你在那里构造的对象是AA对象。

如果需要a的多态行为,则应使用指向动态分配对象的指针。 优选地,智能指针指向动态分配的对象,例如,std::unique_ptr<AA>。 另请注意,AA应该有一个虚拟析构函数。