exponenta event banner

Правило AUTOSAR C++ 14 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