Виртуальный деструктор в C++

Virtual Nyj Destruktor V C



C++ — это язык, который используется для закрепления базовой концепции программирования и укрепляет логическое мышление программистов. В C++ ООП играет жизненно важную роль, поскольку ООП — это объектно-ориентированный язык, который создает объекты классов. В ООП мы изучаем классы и объекты. Классы содержат данные-члены, которые являются переменными разных типов и разными функциями-членами. С помощью экземпляров мы получаем доступ к данным любого класса. Каждый класс имеет свой конструктор и деструктор при создании класса. Конструктор вызывается сам при создании объекта этого класса. Мы также можем инициализировать переменные класса внутри конструктора. Деструкторы также автоматически создаются с помощью конструктора, но деструкторы уничтожают объект, и это последняя функция, которая вызывается перед уничтожением объекта. Создается название класса, например класс «Профессия». Его конструктор — Profession(), а деструктор — ~Profession(). Все трое имеют одинаковое имя.

Поговорив об ООП, конструкторах и деструкторах, давайте теперь поговорим о виртуальных деструкторах. Виртуальные деструкторы, как указано в названии, уничтожают объект. У нас есть базовый класс и производный класс, производный от базового класса. Оба класса имеют свои конструкторы и деструкторы. Виртуальный деструктор освобождает память, выделенную через объект производного класса, при удалении объектов производного класса с помощью указателя базового класса с ключевым словом «виртуальный».

Почему мы используем виртуальный деструктор?

Когда выполнение функций-членов класса завершается или выполнение метода main() подходит к концу, автоматически вызывается деструктор для освобождения памяти, выделенной при создании объекта. Теперь, почему мы используем виртуальный деструктор? Когда удаляется базовый класс, указывающий на производный класс, здесь используется указатель (*). Деструктор базового класса вызывается только во время этого процесса. Деструктор производного класса не вызывается, что приводит к проблемам. Одна из них — проблема с утечкой памяти. Чтобы избежать этой проблемы и сделать наш код безопасным, мы виртуально уничтожаем объекты, чтобы освободить место в памяти, выделенное при создании объектов, путем удаления деструктора базового класса.

Базовый пример C++ без виртуального деструктора

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

Код:

#include <иопоток>

используя пространство имен std ;
класс Parent_Class0
{
общественный :
Родительский_класс0 ( )
{ cout << 'Конструктор родительского класса' << конец ; }
~Родительский_класс0 ( )
{ cout << 'Деструктор родительского класса' << конец ; }
} ;
класс Child_1 : общедоступный Parent_Class0
{
публичный :
Ребенок_1 ( )
{ cout << 'Конструктор дочерних классов' << конец ; }
~Ребенок_1 ( )
{ cout << «Деструктор дочернего класса» << конец ; }
} ;
инт главный ( )
{
Родительский_класс0 * указатель знак равно новый ребенок_1 ( ) ;
удалить указатель ;
возвращаться 0 ;
}

Этот код объясняет, как код выполняется без виртуального деструктора. Прежде всего, создайте класс с именем «Parent_Class0», который будет родительским классом. Внутри этого класса создайте конструктор и деструктор. Как мы знаем, конструктор и деструктор называются так же, как и класс. Деструктор представлен аналогично конструктору, но имеет символ (~), который отличает его от конструктора. Внутри конструктора и деструктора напечатайте сообщение, используя «cout<<». Теперь создайте еще один класс «Child_1». Этот класс является производным от родительского класса «Parent_Class0». Производный класс имеет свой конструктор и деструктор, которые содержат сообщение для печати на экране вывода.

В методе main() мы создаем экземпляр «Parent_Class0» и назначаем ему производный класс. В этом случае важно помнить, что мы используем указатель для извлечения родительского класса. Когда он входит в родительский класс, он выполняет конструктор родительского класса. Затем он переходит к дочернему классу и выполняет его конструктор. Перед выполнением деструктора дочернего класса он должен выполнить деструктор родительского класса. Компилятор выполняет деструктор родительского класса и завершает класс, не выполняя деструктор дочернего класса. Это проблема; он не освобождает память дочернего класса. Он представляет конструктор родительского класса, конструктор дочернего класса и деструктор родительского класса. Это показывает, что деструктор дочернего класса не выполняется. После этого выполнения мы удаляем указатель в функции main().

Вывод:

Пример C++ с виртуальным деструктором

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

Код:

#include <иопоток>

используя пространство имен std ;
класс Parent_Class0
{
публичный :
Родительский_класс0 ( )
{ cout << 'Конструктор родительского класса' << конец ; }
виртуальный ~Parent_Class0 ( )
{ cout << 'Деструктор родительского класса' << конец ; }
} ;
класс Child_1 : общедоступный Parent_Class0
{
публичный :
Ребенок_1 ( )
{ cout << 'Конструктор дочерних классов' << конец ; }
виртуальный ~Child_1 ( )
{ cout << «Деструктор дочернего класса» << конец ; }
} ;
инт главный ( )
{
Родительский_класс0 * указатель знак равно новый ребенок_1 ( ) ;
удалить указатель ;
возвращаться 0 ;
}

Первая программа объясняла проблему, с которой мы сталкиваемся без виртуального деструктора. Теперь этот код решит эту проблему с помощью виртуального деструктора. Во-первых, скопируйте первый код и просто добавьте по одному ключевому слову в двух местах этой программы. Это слово «виртуальный». Вставьте это слово в деструктор родительского класса «Parent_Class0». Точно так же упомяните об этом с деструктором дочернего класса, которым является «Child_1», который является производным от родительского класса. Это «виртуальное» ключевое слово вносит небольшое изменение и сначала выполняет деструктор дочернего класса «Child_1». Затем он выполняет деструктор родительского класса «Parent_Class0». Остальная часть программы работает так же, как и без виртуального деструктора. Добавив этот небольшой фрагмент кода, мы можем уберечь нашу память от утечки. Теперь он отображает четыре сообщения на консоли. Сначала конструктор родительского класса, затем конструктор дочернего класса, деструктор дочернего класса и деструктор родительского класса. В конце мы удаляем указатель в методе main().

Вывод:

C++ Пример чистого виртуального деструктора

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

Код:

#include <иопоток>

класс Parent_0 {
публичный :
виртуальный ~Parent_0 ( ) знак равно 0 ;
} ;
Родитель_0 :: ~Родитель_0 ( )
{
станд. :: cout << «Привет, я Pure Destructor. Ты звал меня!» ;
}
класс Child_0 : общедоступный Родитель_0 {
публичный :
~Ребенок_0 ( ) { станд. :: cout << 'Производный деструктор здесь \n ' ; }
} ;

инт главный ( )
{
Родитель_0 * ptr_0 знак равно новый ребенок_0 ( ) ;
удалить ptr_0 ;
возвращаться 0 ;
}

Родительский класс «Parent_0» создается на первом шаге кода. Внутри него создайте виртуальный родительский деструктор и назначьте ему 0. Это установит виртуальный деструктор в чисто виртуальный деструктор, что означает, что родительский класс теперь является абстрактным, и мы не можем создавать экземпляры этого класса. Вне родительского класса «Parent_0» определите деструкторы и std::cout. Требуемый текст отображается с помощью функции std::cout. Затем создайте класс «Child_0» из родительского класса и определите его деструктор. Внутри деструктора напечатайте сообщение. В функции main() создайте указатель родительского класса и назначьте ему дочерний класс.

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

Вывод:

Заключение

Мы узнали о виртуальном деструкторе, начиная с концепции ООП и заканчивая конструкторами и деструкторами. После объяснения всего этого мы подробно обсудили виртуальный деструктор с примерами кодирования и чистым виртуальным деструктором. Прежде чем объяснять виртуальный деструктор, мы должны знать о конструкторах, деструкторах и наследовании. При наследовании мы наследуем классы от родительского класса. Дочерних классов может быть более одного, но родительский класс — только один. Виртуальные деструкторы и чисто виртуальные деструкторы применяются в наследовании для предотвращения утечки памяти. От базового примера до расширенного примера мы рассмотрели все, что вам нужно знать, чтобы начать использовать и практически уничтожить память производного класса.