Будет ли созданный компилятором деструктор абстрактного базового класса виртуальным?

class Base
{
    virtual void foo() = 0;
    //~Base();     <-- No destructor!
};

Очевидно, что Base будет выведено. Так говорит ли C++ деструктор, сгенерированный компилятором Base должен быть виртуальным?

Спасибо!

4 ответа

Решение

Нет, деструктора не будет virtual если вы не отметите это как таковой. Причина проста - вызовы могут быть сделаны практически как с помощью указателей, так и с помощью ссылок, и то, как и когда вы совершаете вызовы, практически не зависит от того, создаете ли вы объекты с new, Если вы не создаете объекты с new тебе не нужно delete их и так вам не нужны виртуальные деструкторы.

Это не. Это близко к доказательству того, что деструктор не становится автоматически виртуальным:

#include <iostream>

struct BaseBase {
    ~BaseBase() {
        std::cout << "~BaseBase\n";
    }
};

struct Base : BaseBase
{
    virtual void foo() = 0;
    //~Base();     <-- No destructor!
};

struct Derived : Base {
    void foo() { std::cout << "foo\n"; }
    ~Derived() {
        std::cout << "~Derived\n";
    }
};

int main() {
    Base *p = new Derived();
    delete p;
}

Эта программа на самом деле имеет неопределенное поведение, но я сильно подозреваю, что в вашей реализации она не печатает "~Derived". Если Base если бы у него был виртуальный деструктор, то он не имел бы неопределенного поведения и вывел бы "~Derived".

Конечно, это на самом деле ничего не доказывает о стандарте. Любая реализация, на которой вы ее запускаете, может, в конце концов, быть не соответствующей. Но как только вы попробуете это на нескольких, вы поймете, что, что бы ни говорил стандарт, вам нужно указать виртуальный деструктор.

Нет, дтор не гарантированно будет виртуальным.

Когда объявляются классы, специально предназначенные для наследования, рекомендуется явно объявить виртуальный dtor. Обычно это прямой недостаток дизайна. На самом деле, я не могу вспомнить случай, когда не является недостатком дизайна опускать виртуальный dtor из базового класса.

Нет. Класс может иметь виртуальных членов, может быть получен и даже может быть распределен с помощью new и удалены с delete без виртуального деструктора.

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

Конечно, нет никаких причин вообще не объявлять виртуальный деструктор, если ваш класс должен быть производным.

Другие вопросы по тегам