这是一个大得多的代码的缩小问题。我知道C.a应该在堆上,但我想避免改变“。”到“ - >”代码中到处都是。有没有办法可以绕过这个bug? (编译器是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;
};
答案 0 :(得分:1)
您的代码中唯一的错误。您正在调用未定义的行为(实际上有几种不同的方式)。
标准不要求对此进行诊断,编译器不负责确保您不做任何愚蠢的事情。
答案 1 :(得分:1)
new (&a) AB(); // everything works here except virtuals
这不起作用:此处的行为未定义。 a
是AA
类型的对象。您无法在其位置构造类型为AB
的对象。您可以构造的唯一对象是AA
对象。
如果需要a
的多态行为,则应使用指向动态分配对象的指针。优选地,指向动态分配的对象的智能指针,例如std::unique_ptr<AA>
。另请注意,AA
应该有一个虚拟析构函数。