CERT C++: OOP52-CPP

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

Описание

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

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

Реализация Polyspace

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

Примеры

расширить все

Проблема

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

Риск

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

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

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

Одно из возможных исправлений - всегда использовать 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 деструктор. Поэтому, если a Base* указатель указывает на Derived объект, который выделяется памяти динамически, и delete операция выполняется на этом Base* указатель, Base вызывается деструктор. Память, выделенная для дополнительного представителя _d не освобождается.

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

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

  • Чтобы найти, используете ли вы указатель или ссылку на базовый класс для указания на производный объект класса, щелкните правой кнопкой мыши имя базового класса и выберите Search For All References. Просмотрите результаты поиска, которые начинаются с 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. Объектно-ориентированное программирование (OOP)
Введенный в R2019a

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

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

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