Неявный виртуальный или явный виртуальный в унаследованных классах во время компиляции - PullRequest
0 голосов
/ 08 октября 2018

TL; DR Старый код, на который я ссылаюсь, не совместим с C ++.Удивительно, что код когда-либо работал.Вы не можете вызывать виртуальные методы в конструкторах и деконструкторах.

Пир и я обсуждали ключевое слово virtual в C ++.В более старой ОС Ubuntu я работал над программой, которая сообщала об ошибках при вызове «чисто виртуальных методов», чего не должно было быть

class Base {
    virtual ~Base() { this->DoSomethingElse(); }
    virtual bool DoSomething() = 0;
    virtual bool DoSomethingElse() = 0;
};

class Foo : public Base {
    ~Foo();
    bool DoSomething();
    bool DoSomethingElse();
};

// Later...
Base* obj = new Foo();
obj->DoSomething(); // Pure virtual function called SIGABORT
delete obj; // Pure virtual function called SIGABORT

После перехода через отладчик я наконец добавил virtual вунаследованные классы

class Base {
    virtual ~Base() { this->DoSomethingElse(); }
    virtual bool DoSomething() = 0;
    virtual bool DoSomethingElse() = 0;
};

class Foo : public Base {
    virtual ~Foo();
    virtual bool DoSomething();
    virtual bool DoSomethingElse();
};

// Later...
Base* obj = new Foo();
obj->DoSomething(); // Ok!
delete obj; // Ok!

Я дважды проверил в Google все, что могло бы предположить, что virtual было необходимо для унаследованных классов, прежде чем сообщить об этом моему коллеге.Они сказали, что да, виртуальная среда необходима в стандарте, но в большинстве случаев компиляторы автоматически заполняют виртуальную для унаследованных классов.Из моего понимания (и я полагаю, что большинство программистов) виртуальная необходима, когда вы хотите переопределить эту функцию с помощью полиморфизма.Но было неясно, что вам нужно пометить реализации функций дочернего класса.

Я удивлен нехваткой ресурсов по теме.Так что же это?Подразумевается ли виртуальность в современных компиляторах C ++ и где стандарт описывает это?

1 Ответ

0 голосов
/ 08 октября 2018

Функция, которая переопределяет виртуальную функцию, является виртуальной.Здесь проблема не в этом.

Проблема заключается в вызове DoSomethingElse() (с или без избыточности this->) в деструкторе для Base.Когда конструктор или деструктор вызывает виртуальную функцию, он отправляет версию функции, которая принадлежит классу, чей конструктор или деструктор вызывается, not версии для класса, производного от этого класса.Так что этот вызов в деструкторе вызывает Base::DoSomethingElse(), который является вызовом чисто виртуальной функции, и поэтому среда выполнения прерывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...