exponenta event banner

CERT C++: OOP52-CPP

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

Описание

Определение правила

Не удаляйте полиморфный объект без виртуального деструктора. [1 ]

Внедрение Polyspace

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

Примеры

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

Проблема

Деструктор базового класса не является виртуальным, если класс имеет 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;
};

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

Группа: 09. Объектно-ориентированное программирование (ООП)
Представлен в R2019a

[1] Данное программное обеспечение было создано компанией MathWorks и включает в себя следующие компоненты: «Веб-сайт SEI CERT-C», © 2017 Университет Карнеги-Меллон, веб-сайт SEI CERT-C + + © 2017 Университет Карнеги-Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги-Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги-Меллон, со специальным разрешением от его Института программного обеспечения.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОНА И/ИЛИ ЕГО ПРОГРАММНОГО ИНЖЕНЕРНОГО ИНСТИТУТА, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ КАК ЕСТЬ. УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБЫХ ВОПРОСОВ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ ТОВАРНОЙ ПРИГОДНОСТИ, ИСКЛЮЧИТЕЛЬНОСТИ ИЛИ РЕЗУЛЬТАТОВ, ПОЛУЧЕННЫХ ОТ ИСПОЛЬЗОВАНИЯ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Данное программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллона или его Институтом разработки программного обеспечения.