CERT C++: OOP52-CPP

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

Описание

Управляйте определением

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

Примеры

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

Описание

Деструктор базового класса, не виртуальный, происходит, когда класс имеет функции 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, не выпущена.

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

  • Чтобы найти классы выведенными от базового класса, щелкните правой кнопкой по имени базового класса и выберите 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 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

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