C ++ наследование не работает в стеке? - PullRequest
0 голосов
/ 09 февраля 2012

Это проблема уменьшенного размера гораздо большего кода. Я знаю, что 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;
};

Ответы [ 2 ]

1 голос
/ 09 февраля 2012
new (&a) AB();  // everything works here except virtuals

Это на самом деле не работает: поведение здесь не определено. a - это объект типа AA. Вы не можете построить объект типа AB на его месте. Единственный объект, который вам разрешено построить, это AA объект.

Если вам нужно полиморфное поведение для a, вы должны использовать указатель на динамически размещенный объект. Предпочтительно, умный указатель на динамически размещенный объект, например, std::unique_ptr<AA>. Также обратите внимание, что AA должен иметь виртуальный деструктор.

1 голос
/ 09 февраля 2012

Единственная ошибка в вашем коде. Вы вызываете неопределенное поведение (на самом деле несколькими различными способами).

Стандарт не требует диагностики для этого, компилятор не несет ответственности за то, чтобы вы не делали глупостей.

...