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