МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
Національний університет “Львівська політехніка”
Кафедра САП
Звіт
до лабораторної роботи № 9
Перевантаження функцій і операторів, спадкування
з курсу “Проблемно-орієнтоване програмування”
для студентів спеціальності "Комп’ютерні системи проектування"
Львів 2013
1. МЕТА РОБОТИ
Мета роботи - ознайомитися з можливостями перевантаження функцій та використання принципів спадкування в об’єктно-орiєнтованій мові програмування С++.
2. ТЕОРЕТИЧНІ ВІДОМОСТІ
2. 1. Перевантаження функцій
Перевантаження функцій є одним із різновидів поліморфізму. У мові C++ допускається використання функцій з однаковими іменами, але різними оголошеннями параметрів. У таких випадках говорять, що функції перевантажені, а сам процес називається перевантаженням функцій.
Як правило, щоб перевантажити якусь функцію, досить визначити три її різні версії, а компілятор сам подбає про іншому. Однак варто пам'ятати про одне важливе обмеження: тип і/або кількість параметрів кожної перевантаженої функції повинні бути різними. Не можна перевантажити функції, які відрізняються лише типом значення, що повертається. Цього зовсім недостатньо, оскільки необхідно, щоб типи й/або кількість параметрів у кожній версії відрізнялися друг від друга. (Інформації про тип значення, що повертається, недостатньо для того, щоб компілятор правильно розпізнав потрібний варіант перевантаженої функції.) Зрозуміло, це не означає, що функції, які перевантажуються, повинні мати однаковий тип значення, яке повертається.
2.2. Перевантаження операторів
Поліморфізм у мові C++ проявляється також у вигляді перевантаження операторів. Як відомо, для вводу й виводу в мові C++ застосовуються оператори ">>" і "<<". Це стало можливим завдяки тому, що в заголовному файлі <iostream> ці оператори перевантажені. Перевантажені оператори мають різний сенс для різних класів, зберігаючи при цьому своє первісне значення.
У мові C++ можна перевантажити майже всі оператори. Повернемося, наприклад, до класу stack, розглянутому нами вище. У цьому класі можна перевантажити оператор "+", змусивши його складати два об'єкти класу stack. При цьому оператор "+" зберігає свій первинний зміст.
2.3. Спадкування
Як вказувалося раніше, спадкування є однієї з основних характерних рис об’єктно-орієнтованого програмування. У мові C++ спадкування виражається тім, що один клас може здобувати властивості іншого класу в момент свого оголошення. Спадкування дозволяє створювати ієрархії класів, уточнюючи їхньої властивості від самих загальних до більше конкретних. Процес спадкування починається з визначення базового класу (base class), властивості якого будуть загальними для всіх його спадкоємців. Базовий клac являє собою опис найбільш загального характеру. Спадкоємці базового клacу називаються похідними класами (derived classes). Похідний клас має всі властивості базового класу й своїх специфічних особливостей. Продемонструємо цей механізм на прикладі, у якому описуються різні типи будинків.
У загальному випадку похідний клас оголошується в такий спосіб.
class похідний_клас : специфікатор_доступу базовий_клас
{
// тіло нового класу
}
Тут специфікатор_доступу вказувати необов'язково. Цей параметр може приймати три значення: public, private або protected.
Похідний клас має прямий доступ як до своїх членів, так і до відкритих членів базового класу.
Як бачимо, основна перевага механізму спадкування полягає в тім, що можна спочатку створити загальну класифікацію, а потім на її основі розробити уточнюючі класи. Таким чином, кожний об'єкт може точно представляти свій власний підклас.
У книгах про мову C++ відношення спадкування часто описують за допомогою термінів базовий клас і похідний клас. Однак поряд з ними часто згадуються терміни предок і спадкоємець. Крім того, можна зустріти поняття суперклас і підклас. Крім можливості створювати ієрархічну класифікацію, спадкування забезпечує підтримку динамічного поліморфізму за допомогою механізму віртуальних функцій.
2.4. Конструктори й деструктори
Дуже часто деяка частина об'єкта перед його першим використанням повинна бути ініціалізована.
Оскільки ініціалізація об'єктів дуже розповсюджена вимога, у мові C++ передбачений особливий механізм, що дозволяє ініціалізувати об'єкти в момент їхнього створення. Ця автоматична ініціалізація здійснюється конструктором.
Конструктор — це особлива функція, що є членом класу. Її ім'я повинне збігатися з ім'ям класу. Наприклад, клас stack можна модифікувати, передбачивши в ньому конструктор.
Конструктор автоматично викликається в момент створення об'єкта, тобто при його оголошенні. Отже, оголошення об'єкта в мові C++ - це не пасивний запис, а активний процес. У мові C++ оголошення є виконуваним оператором. Це розходження носить зовсім не академічний характер. Код, за допомогою якого конструюється об'єкт, може бути досить важливим. Для глобальних і статичних локальних об'єктів конструктори викликаються лише один раз. При оголошенні локальних об'єктів конструктори викликаються щораз при вході у відповідний блок.
Антиподом конструктора є деструктор. У багатьох ситуаціях об'єкт повинен виконати деяку дію або дії, які знищать його. Локальні об'єкти створюються при вході у відповідний блок, а при виході з нього вoни знищуються. При руйнуванні об'єкта автоматично викликається його деструктор. Для цього існує кілька причин. Наприклад, об'єкт повинен звільнити займану їм пам'ять або закрити файл, відкриттів їм раніше. У мові C++ ці дії виконує деструктор. Ім'я деструктора повинне збігатися з ім'ям конструктора, і перед ним ставиться знак ~ (тильда).
Конструктори й деструктори не повертають ніяких значень.
ЗАВДАННЯ ДО ЛАБОРАТОРНОЇ РОБОТИ(1 варіант)
Використовуючи перевантаження функцій – написати програму, яка б вираховувала абсолютну величину цілого (abs), довгого цілого (labs) і числа з плаваючою комою (fabs), використовуючи одне ім’я abs.
КОД ПРОГРАМИ
#include <iostream.h>
int abs(int i);
double abs(double d);
long abs(long l);
int main(){
cout<< abs(-10)<<"\n";
cout<< abs(-11.0)<<"\n";
cout<<abs(-9L)<<"\n";
return 0;
}
int abs (int i) {cout<<"Function abs() of the type int \n";
return i<0 ? -i : i;
}
double abs (double d) { cout << "Function abs() of the type double\n";
return d<0.0 ? -d : d;
}
long abs(long l) { cout << "Function abs() of the type long \n";
return l<0 ? -l : l;
}
РЕЗУЛЬТАТ ВИКОНАННЯ
ВИСНОВОК
На основі лабораторної роботи я ознайомився з можливостями перевантаження функцій та використання принципів спадкування в об’єктно-орiєнтованій мові програмування С++.