Ошибка сегментации от вызова функции в деструкторе

0

Почему этот код компилируется и правильно печатает "Derived"?

template <class Derived>
class Base
{
public:
    Base(Derived& d) : derived(d) {}
    void f() { std::cout << "Base\n"; }
    virtual ~Base() { derived.f(); }
private:
    Derived& derived;
};

class Derived : public Base<Derived>
{
public:
    Derived() : Base<Derived>(*this) {}
    void f() { std::cout << "Derived\n"; }
};

int main()
{
    Derived d;
}

Но либо создание Base::f virtual либо как Derived::f и Base::f виртуальных вызывает "Base" для печати. Кроме того, изменение Derived::f на virtual дает Invalid memory reference (SIGSEGV). Я ожидаю, что эти два других случая напечатают "Derived", так как я называю это из экземпляра Derived.

Почему это происходит?

  • 0
    Какие-либо предупреждения получены?
  • 0
    @πάνταῥεῖ πάνταῥεῖ Никаких предупреждений.
Показать ещё 8 комментариев
Теги:

1 ответ

2
Лучший ответ

Это болтливая ссылка.

Вы инициализируете поле Base::derived как ссылку на объект Derived через конструктор Derived, но затем вы получаете доступ к нему в деструкторе Base после уничтожения объекта Derived.

Доступ к любому объекту после его уничтожения (с помощью указателя или ссылки) является неопределенным поведением, поэтому может случиться что угодно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню