Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП_KAZYMYR.doc
Скачиваний:
14
Добавлен:
09.11.2019
Размер:
3.71 Mб
Скачать

Розділ 4 поліморфізм

4.1.Віртуальні методи

Поліморфізм буквально означає мати безліч форм (Webster's New Word Dictionary). В ООП під поліморфізмом розуміється здатність об'єктів реагувати на однакові повідомлення згідно з типом об'єктів.

Розглянемо приклад ієрархії класів мовою С++:

class Base {

public:

void f();

}

class A: public Base {

public:

void f();

}

class B: public Base {

public:

void f();

}

Тут всі класи мають однойменну функцію f().

Тепер складемо основну програму:

void main (){

Base * base_ptr[2];

base_ptr[0] = new A;

base_ptr[1] = new B;

for (int i=0; i < 2; i++) base_ptr[i] ( f();

}

Виникає питання: яка функція буде викликатися в циклі? При такому визначенні класів у циклі буде викликатися функція f() класу Base, тому що base_ptr оголошений, як масив покажчиків на клас Base. Подібне зв'язування методів з покажчиками на клас називається статичним або раннім зв'язуванням. Воно встановлюється на етапі компіляції.

Для того, щоб розірвати зв'язок, установлений при раннім зв'язуванні, і забезпечити виклик методів об'єкта на який безпосередньо вказує покажчик, існує механізм віртуальних методів. Оголошення методу віртуальним виконується за допомогою ключового слова virtual, що ставиться перед назвою відповідного методу:

class Base {

public:

virtual void f();

}

class A: public Base {

public:

virtual void f();

}

class B: public Base {

public:

virtual void f();

}

Ключове слово virtual означає, що функція f() може мати різні версії в похідних класах. Але в результаті, зв'язок об'єкта з необхідною версією викликуваного методу буде встановлена не на етапі компіляції, а на етапі виконання програми. Такий зв'язок об'єктів з методами називається динамічним або пізнім зв'язуванням.

4.2.Віртуальні функції в С++

Особливості застосування віртуальних методів у С++ полягають у наступному:

  1. Віртуальні функції не можуть бути оголошені як статичні.

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

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

  3. Віртуальна функція, обумовлена в базовому класі, не обов'язково повинна перевизначатися в похідному класі, вона буде успадковуватися.

  4. Віртуальна функція не може бути “дружньою функцією”.

  5. Елементом похідного класу може бути функція однойменна, але така, що відрізняється типом або числом параметрів з віртуальною функцією базового класу, але в цьому випадку вона не є віртуальною.

  6. Для забезпечення віртуального виклику об'єкт потрібно оголосити через покажчик або посилання. Без ключового слова virtual динамічний тип змінної (навіть для покажчиків і посилань) ігнорується. Базовий клас повинен бути відкритим.

Віртуальний виклик дозволяє порушити заборону на звертання до методів похідних класів через посилання на базовий клас:

class X {

public:

virtual void f();

};

class Y: public X {

private:

virtual void f();

};

void main () {

Y y;

X * x_ptr=&y;

x_ptr ( f(); // буде викликана функція Y::f()

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]