AUTOSAR C++14 Rule A12-4-1

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

Описание

Управляйте определением

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

Объяснение

Если деструктор базового класса не является общедоступным виртуальным или общедоступным переопределением, класс не может вести себя полиморфно для удаления объектов производного класса.

Если указатель на базовый класс относится к объекту производного класса, и вы используете указатель, чтобы удалить объект:

class Base {
  public:
    ~Base() {}
};
    
class Derived: public Base {
  public:
    ~Derived() {}
};
...
void func(Base* ptr) {
    //ptr might point to a Base or Derived object
    delete ptr;
}
только деструктор базового класса называется. Дополнительные средства, выделенные в производном классе, не высвобождены и могут вызвать утечку ресурсов. Смотрите пример ниже.

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

Реализация Polyspace

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

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

развернуть все

#include <new>

class Base {
  public:
    Base() {}
    ~Base() {} //Noncompliant
};
    
class Derived: public Base {
     int *arr;
  public:
     Derived() {
        arr = new int(5);
     }
    ~Derived() {
        delete arr;
     }
};

void main() {
    Base* basePtr = new Derived();
    delete basePtr;
}

В этом примере, класс Base имеет невиртуальный деструктор. В результате, когда указатель basePtr удален, только деструктор класса Base вызывается. Однако basePtr точки к объекту класса Derived. Удаление не завершено потому что деструктор класса Derived не вызывается. В частности, элемент данных arr в производном объекте не удален.

Проверяйте информацию

Группа: Специальные функции членства

Введенный в R2020a