exponenta event banner

Деструктор базового класса не является виртуальным

Класс не может вести себя полиморфно при удалении производных объектов класса

Описание

Этот дефект возникает, когда класс имеет virtual функции, но не virtual деструктор.

Риск

Наличие virtual функции указывают, что класс предназначен для использования в качестве базового класса. Однако, если класс не имеет virtual деструктор не может вести себя полиморфно для удаления производных объектов класса.

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

Зафиксировать

Одно из возможных исправлений - всегда использовать virtual деструктор в классе, содержащем virtual функции.

Примеры

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

class Base {        
        public:
                Base(): _b(0) {};
                virtual void update() {_b += 1;};
        private:
                int _b;
};

class Derived: public Base {                     
        public:
                Derived(): _d(0) {};
                ~Derived() {_d = 0;};
                virtual void update() {_d += 1;};
        private:
                int _d;
};

В этом примере класс Base не имеет virtual деструктор. Поэтому, если Base* указатель указывает на Derived объект, который динамически выделяется памяти, и delete операция выполняется на Base* указатель, Base вызывается деструктор. Память, выделенная для дополнительного члена _d не освобождается.

Дефект появляется в определении базового класса. Ниже приведены некоторые советы по навигации в исходном коде:

  • Чтобы найти классы, производные от базового класса, щелкните правой кнопкой мыши имя базового класса и выберите «Поиск всех ссылок». Просмотрите каждый результат поиска, чтобы найти производные определения классов.

  • Чтобы определить, используется ли указатель или ссылка на базовый класс для указания на производный объект класса, щелкните правой кнопкой мыши имя базового класса и выберите «Поиск всех ссылок». Просмотр результатов поиска, начинающихся с Base* или Base& для поиска указателей или ссылок на базовый класс. Затем можно увидеть, используется ли указатель или ссылка для указания на производный объект класса.

Исправление - Сделать виртуальный деструктор базового класса

Одной из возможных корректировок является объявление virtual деструктор для класса Base.

class Base {        
        public:
                Base(): _b(0) {};
                virtual ~Base() {_b = 0;};
                virtual void update() {_b += 1;};
        private:
                int _b;
};

class Derived: public Base {                     
        public:
                Derived(): _d(0) {};
                ~Derived() {_d = 0;};
                virtual void update() {_d += 1;};
        private:
                int _d;
};

Информация о результатах

Группа: Объектно-ориентированная
Язык: C++
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: DTOR_NOT_VIRTUAL
Воздействие: среднее
Представлен в R2015b