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

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

Описание

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

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

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

Введенный в R2015b