Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекція №6 Поліморфізм.doc
Скачиваний:
4
Добавлен:
16.11.2019
Размер:
86.02 Кб
Скачать

Віртуальні деструктори

Конструктори не можуть бути віртуальними, однак деструктори можуть бути віртуальними, і часто ними є. Розглянемо базовий клас із віртуальним деструктором. Повідомляємо вказівник на об'єкт базового класу й передаємо йому адреса об'єкта похідного класу. Така операція припустима й часто використовується.

При видаленні об'єкта похідного класу буде викликаний деструктор похідного класу. Потім деструктор похідного класу викличе деструктор базового класу, і об'єкт буде правильно вилучений (вилучений цілком).

Якщо деструктор базового клас не є віртуальним, то буде викликаний тільки деструктор базового класу й відбудеться витік пам'яті.

class Coord

{

protected:

double x, y ;

public:

Coord ( ) { x = 0 ; y = 0 ; }

virtual ~Coord ( ) { cout<<"Delete x, y\n" ; }

} ;

class Dot : public Coord

{

char name ;

public:

Dot (char N ) : Coord ( ) { name = N ; }

~Dot ( ) { cout<<"Delete name \n" ; }// вірт деструктор похідного класу

} ;

Void main ( )

{

Coord* pc ;

pc = new Dot ('D') ; // передає йому адреса об'єкта похідного класу

delete pc ; // видаляє об'єкт похідного класу

}

Тому що оголошений у похідному класі Dot деструктор є віртуальним, то інструкція

delete pc ;

кваліфікується як виклик Dot :: ~dot ( ) і видалення об'єкта відбувається правильно. При виконанні програма виводить на екран:

Delete name

Delete x, y

Якщо ж зробити деструктор базового класу не віртуальним, то й деструктор похідного класу не буде віртуальним. Виходить, використання попередньої інструкції буде кваліфіковано як виклик Coord :: ~Coord ( ), що викличе видалення тільки пам'яті, що належить класу Coord. При виконанні програма виведе на екран:

Delete x, y

У зв'язку із цим можна сформулювати наступні правила:

  1. віртуальний деструктор доцільно використовувати, якщо в базовому класі є віртуальні функції;

  2. віртуальні функції доцільно використовувати тільки в тому випадку, якщо програма містить і базовий, і похідний класи;

Абстрактні класи й чисто віртуальні функції

Класи можуть бути створені для того, щоб визначити протокол взаємодії з об'єктами. Ці класи називаються "абстрактними", тому що ніякий об'єкт цього класу не може бути створений. Вони існують винятково для створення похідних класів.

Абстрактний клас – це клас, що містить, щонайменше, одну чисто віртуальну функцію. Похідні від нього класи повинні реалізовувати ці чисто віртуальні функції, інакше, якщо залишиться хоч одна нереалізована чисто віртуальна функція, такий клас також буде абстрактним. Чисто віртуальна функція оголошується за допомогою наступного синтаксису:

virtual <ім'я_функції>(<список параметрів>) = 0 ;

Припустимо, проектується ієрархія класів, причому базовий клас цієї ієрархії з іменем Coord повинен забезпечити загальні функціональні можливості, але об'єкти типу Coord є занадто загальними, щоб бути корисними. У цьому випадку клас Coord є гарним кандидатом в абстрактні класи:

class Coord

{

protected:

double x, y ;

public: // відкриті члени класу

Coord ( ) { x = 0 ; y = 0 ; } // конструктор базового класу

virtual void Print ( ) = 0 ; // повідомляє чисто віртуальну функцію

} ;

class Dot : public Coord

{

char name ; // ім'я точки

public: // відкриті члени класу

Dot (char N ) : Coord ( ) { name = N ; } // викликає конструктор базового класу

} ;