Методичні вказівки до лабораторної роботи №2 на тему Перевизначення операторів
« НазадМетодичні вказівки до лабораторної роботи №2з курсу Програмування (мова програмування С) на тему: Перевизначення операторівМета: навчитися організовувати класи та перевантажувати (перевизначати) для них оператори: бінарні, унарні, логічні та операторів відношення; визначати та оперувати об’єктами цих класів. Обладнання: ПК, програмне забезпечення Borland C++, методичні вказівки та завдання до лабораторної роботи. Методичні вказівки Перевантаження операторів – це можливість призначати новий сенс операторам при використанні їх з певним класом. Використовуючи перевантаження операторів, ви можете підвищити легкість читання ваших програм і полегшити їх розуміння, виражаючи операції класу зрозумілішим чином. Класи дають засіб специфікації в C++ представлення неелементарних об’єктів разом з множиною дій, які можуть над цими об’єктами виконуватися. Можна визначати арифметичні, логічні операції, операції порівняння, виклику () та індексування [], а також можна перевизначити присвоєння та ініціалізацію. Можна визначити явне і неявне перетворення між визначеними користувачем і основними типами. Не можна перевантажувати операції: “.”, “::”, “.*”, “?” і оператори препроцесора. Для перевантаження оператора використовується оператор-функція або операторна функція. Частіше всього оператор-функція є членом класу або дружня функція класу, для якого вона визначена. Операторна функція член класу визначається таким чином: <тип результату> operator@(<список аргументів>); де тип результату – будь-який тип (часто типом, є клас, для якого оператор-функція визначена), @ – це символ операції, що піддається перевантаженню, вмістиме списку аргументів залежить від типу операції, яка перевантажується. В дружній функції вказівник this не передається. У разі бінарного оператора це означає, що дружній оператор-функції явно передаються обидва операнди, а у разі унарної – один. Інші типи операцій аналогічні оператор-функціям членам класу. Операторна дружня функція класу визначається таким чином: friend <тип результату> operator@(<список аргументів>); Зауваження! По-перше, не можна міняти пріоритети операторів. По-друге, не можна міняти число операндів оператора. По-третє, оператор-функція не може мати параметри по замовчуванню. Перевизначення бінарних операторів. Коли оператор-функція – член класу перенавантажує бінарний оператор, у функції буде тільки один параметр. Цей параметр отримає той об’єкт, який розташований праворуч від оператора. Об’єкт зліва генерує виклик оператор-функції і передається неявно, за допомогою вказівника this. Перевизначення операторів відношення та логічних операторів. При перевизначенні операторів відношення та логічних операторів так, щоб вони вели себе звичним чином, не потрібні оператор-функції, які повертають об’єкт класу, для якого ці функції визначені. Замість цього вони повинні повертати ціле значення, яке інтерпретується як значення true або false. Перевизначення унарних операторів. Коли оператор-функція – член класу перенавантажує унарний оператор, у функції не буде параметрів. Оскільки є тільки один операнди, він генерує виклик оператор-функції. Приклад для ілюстрації пере визначення різних типів операцій: 1. Приклад демонструє можливості використання бінарних, унарних, операторів порівняння та логічних операторів визначених в середині класу, а також визначення дружніх оператор-функція. class Point { // тип, визначуваний програмістом int x, y; // закриті дані public: // загальнодоступні функції-члени
Point() { x=0; y=0; } // конструктор
Point(int r, int i) { re=r; im=i; } // конструктор
Point operator+(Point); // додавання двох об’єктів
Point operator+(int); // додавання до об’єкту цілого значення
friend Point operator+(Point, Point); // дружня оператор-функція friend Point operator+ (Point &, int); // дружня оператор-функція friend Point operator+ (int, Point &); // дружня оператор-функція Point operator-(); // унарний –
Point operator++(); // префіксна форма оператора інкремента
Point operator++(int); // постфіксна форма оператора інкремента
Point& operator=(Point&); // оператор присвоєння bool operator&&(Point); // оператор логічне і }; // кінець класу Point // перевантаження бінарний оператор додавання двох об’єктів
Point Point:: operator+(Point c) {
Point tmp;
tmp.x=x+c.x; tmp.y=y+c.y;
return tmp;
}
// перевантаження бінарний оператор додавання до об’єкту цілого значення
Point Point:: operator+(int c) { Point tmp;
tmp.x=x+c; tmp.y=y+c;
return tmp;
}
//перевантаження оператора додавання об’єктів за допомогою дружньої функції Point operator+(Point& c, Point& z) { Point tmp; tmp.x = с.х + z.x; tmp.y = с.y + z.y; return tmp; } //... Point Point:: operator-() { x=-x; y=-y; } // перевантаження унарного віднімання Point Point:: operator++() { x++; y++; } // перевантаження префіксного інкремента Point Point:: operator++(int) { ++x; ++y; } // перевантаження постфіксного інкремента Point& Point::operator=(Point& c) { // перевантаження оператор присвоєння if (this = &rhs) return *this; // перевірка присвоєння самому собі x = c.x; у = c.y; return *this; // повернути ліву частину } bool Point::operator&&(Point с) { // перевантаження логічного оператора return (x && с.x) && (у && с.y); } Перевизначення оператора індексування []. Відповідна функція operator[] може бути визначена як нестатична компонент функція класу А, а також любоrо похідного від А класу. Звернення до неї здійснюватиметься в наступній формі: oA[i], дe перший операнд оА це об’єкт класу А, в якому описана функція operator, другий операнд це параметр, що передається функції operator. Вираз oA[i] інтерпретується як oA.operator[](i). Функція operator[] може бути використана для передачі значення індексу в клас і набуття значення елементу масиву класу із заданим індексом. Розглянемо простий приклад: #define k 10 class string { char* p_string; unsigned size; pubIic: string (unsigned s) { p_string=new char[size=s]; } ~string() { delete[] p_string; } char& operator[](int); }; char& string::operator[](int i) { if((i<0)||(i>=size)) { cout<<"неправильный индекс\n"; i=0; } return p_string[i]; } main() { string my_string(k); for(int j=0; j<k; j++) my_string[j] = j+'0'; for(j=k-1;j>=0; j--) cout<<my_string[j]; cout << endl; } Тут функція operator[] перевіряє правильність значення індексу (т. е., що індекс лежить в діапазоні допустимих значень індексу для заданоrо масиву), передає індекс мaсиву p_string з атрибутом private (цей масив задається через вказівнчик на йоro початок) і повертає значення відповідного елементу масиву. Під час виконання завдання лабораторної роботи переконаєтеся, що ви освоїли наступне: 1. Щоб перенавантажувати оператора, ви повинні визначити клас, якому оператор буде призначений. 2. Коли ви перенавантажуєте оператор, перевантаження діє тільки для класу, в якому він визначається. Якщо програма використовує оператора з некласовими змінними (наприклад, змінними типу int або float), використовується стандартне визначення оператора. 3. Щоб перенавантажувати оператор класу, використовуйте ключове слово C++ operator для визначення методу класу, який C++ викликає кожного разу, коли змінна класу використовує оператор. 4. C++ не дозволяє вашим програмам перевантажувати оператор вибору елементу (.), оператора покажчика на елемент (.*), оператора дозволу зоні видимості (::) і умовного оператора порівняння (?:). Завдання до лабораторної роботи №2 Побудувати конкретний клас (у відповідності до варіанту), з врахуванням необхідності приховання даних, в якому передбачити: конструктори (в тому числі за замовченням і конструктор копії), деструктор, функції – модифікатори і функції – селектори. Функції – члени мають бути визначені за межами класу. Перевантажити операції “=”, потокового введення-виведення як такі, що вводять і виводять повну інформацію про об’єкт в певному форматі, і інші у відповідності до варіанту. Самостійно продумати і реалізувати спосіб демонстрації отриманих результатів. Варіант 1. 1. Клас “учасник”: прізвище, телефон, адреса. 2. Додаткові класи: “учасник черги на отримання житла” (дата постановки на облік, наявність пільг, порядковий номер в черзі); “учасник виїзної конференції” (чи потребує поселення, тривалість доповіді, час початку роботи конференції, час початку виступу даного доповідача). 3. В класах перевантажити бінарні операції порівняння (“<“ та “!=“) – за датою поставлення на облік і тривалістю доповіді; унарний “-“ – для зміни пункту про наявність пільги і про потребу в поселенні – на протилежне значення. Варіант 2. 1. Клас “фігура”: координати на шахівниці, колір. Метод – “хід” – в одному з двох напрямків. 2. Додаткові класи: “шашка” – (порядковий номер) і “дамка”, методи – “хід” і “удар”. 3. В класах перевантажити бінарну функцію А/В як “А б’є В” і оператор перетворення типу (із “шашка” в “дамка”). Варіант 3. 1. Клас “нота”: назва, октава, тривалість звучання. 2. Додаткові класи: “звук” (частота) і “зображення” (координати на екрані лівого верхнього кута фрагменту нотного стану). В обох класах – порядковий номер ноти, визначити функцію output – для кожного класу з різною реалізацією. 3. В класах перевантажити операції постфіксний ++ – для отримання наступної ноти, префіксний ++ - для збільшення тривалості звучання ноти вдвічі. Варіант 4. 1. Клас “іграшка”: ціна, назва, кількість на складі. 2. Додаткові класи: “машина” (наявність дистанційного керування, порядковий номер) і “м’яка іграшка” (матеріал, звук). В усіх класах визначити функцію print – для кожного класу з різною реалізацією. 3. В класах перевантажити операції “++” – як збільшення кількості на складі; “<” – як порівняння цін. Варіант 5. 1. Клас “Товар”: назва, порядковий номер, постачальник, ціна, кількість одиниць. 2. Додаткові класи: “Промисловий товар” (умови транспортування, місце знаходження: на складі, в торговому залі, на вітрині) і “Харчовий продукт” (дата виготовлення, термін зберігання). В усіх класах визначити функцію alarm() – для промислового товару з повідомленням із умов транспортування (“не кантовать”, “осторожно!”,...), або “товар непридатний для споживання” – для харчового, для “Товар” – просто назва товару. 3. В класах перевантажити операції “++” – як збільшення кількості одиниць для харчового і зміна місця знаходження для промислового; “<” – порівняння за терміном зберігання для харчового і за ціною для промислового. Варіант 6. 1. Клас “Точка на площині”: координати. 2. Додаткові класи: “комплексне число” і “раціональний дріб”. В усіх класах визначити функцію print – для друку назви класу, до якого належить об’єкт. 3. В класах перевантажити операції “<” і “+” бінарні і “-” унарний – у відповідності до їх семантики. Варіант 7. 1. Клас “Точка на площині”: координати. 2. Додаткові класи: “коло” (радіус) і “прямокутник” (координати протилежного кута). В усіх класах визначити функцію move – для руху об’єкта на 1 позицію по x і по y. 3. В класах перевантажити операції “++” – як збільшення розміру об’єкта на 1, “<” – за розміром і С=А+В – об’єкт С – “концентричний” відносно А і більший на відповідні розміри об’єкта В. Варіант 8. 1. Клас “учасник змагань”: країна, вид спорту, назва учасника. 2. Додаткові класи: “футбольна команда” (кількість забитих голів, результат, порядковий номер) і “легкоатлет” (час, час лідера, відставання від лідера, місце у фінальній таблиці). В усіх класах визначити функцію print – друк тільки назви учасника або і назви і кількості голів для футбольної команди або часу для легкоатлета. 3. В класах перевантажити операцію “++” – як збільшення на 1 кількості забитих голів або зменшення на 1 місця в фінальній таблиці; бінарний “-” – як результат конкретної гри: “нічия”, “перемога” або “поразка” в полях “результат”. Для об’єктів легкоатлет А-В щось виконує тільки для ситуації, коли А стає новим лідером, тобто його час менший, ніж час лідера, тоді необхідно змінити відповідні значення для обох об’єктів. Варіант 9. 1. Клас “Станція”: координати, назва. 2. Додаткові класи: “Радіостанція” (досяжність, вартість ефірного часу, діапазон частот, порядковий номер), “Залізнична станція” (кількість запасних шляхів, тривалість зупинки швидкісних потягів, категорія, порядковий номер), визначити функцію view – для кожного класу з різною реалізацією (назва і категорія). 3. В обох класах перевантажити бінарну операцію “+”: результуючий об’єкт для радіостанцій має сумарну досяжність, мінімальну вартість ефірного часу і об’єднання діапазону частот, для залізничних – сумарну кількість запасних шляхів, максимальну категорію і максимальну тривалість зупинки. Унарна “++” – збільшення відповідно вартості ефірного часу і кількості запасних шляхів. Варіант 10. 1. Клас “кліматичні умови”: температура. освітленість. вологість, кислотність грунта. 2. Додаткові клас: “кліматичні умови в теплиці”(оптимальні кліматичні умови, допуски), “кліматичні умови на городі” (критичний рівень вологості, критичні рівні кислотності), визначити функцію show – для “кліматичні умови” – поточний стан, для додаткових класів – виводити тільки ті значення, які перевищують критичні, і величину цього перевищення. 3. В обох класах перевантажити бінарну операцію “= =”, якщо всі параметри обох об’єктів лежать в межах допустимих, або якщо для обох об’єктів є хоч один параметр, що знаходиться за цими межами і унарну – префіксний “++” для збільшення рівня вологості на 1. Варіант 11. 1. Клас “товар на складі”: назва, кількість, місце розташування). 2. Похідні: “продукт з малим терміном зберігання”(оптимальна температура, дата поставки, термін зберігання), “хімічний елемент”(оптимальна температура. оптимальна вологість, допуски по температурі і вологості), визначити функцію attention – для кожного класу з різною реалізацією. 3. В обох класах перевантажити бінарну операцію “<” за датою поставки і за амплітудою критичних температур, і унарну “++” – збільшення кількості товарів відповідного класу. Функцію attention перетворити на віртуальну. Варіант 12. 1. Клас “книга”: код УДК, назва, автор, рік видання, кількість сторінок. 2. Похідні: “Книга в бібліотеці”(інвентарний номер, ознака наявності, кому видана, вартість), “книга в магазині”(відпускна ціна, кількість екземплярів), визначити функцію view – для кожного класу з різною реалізацією. 3. В усіх класах перевантажити бінарні операції “= =” – за кодом УДК, “<“ – за вартістю, відпускною ціною або кількістю екземплярів, в залежності від класу і унарну “++” – збільшити кількість екземплярів, а для бібліотечної – якщо книга не видана, то змінити ознаку наявності і в інтерактивному режимі за повнити поле “кому видана”. Функцію view перетворити на віртуальну. Варіант 13. 1. Клас “банківський рахунок”: назва банку, номер рахунку, МФО. 2. Похідні: “депозитний” (дата відкриття, період, ставка, сума), “розрахунковий” (дата останньої операції, ставка, залишок), визначити функцію print – для кожного класу з різною реалізацією (номер і категорія). 3. В обох класах перевантажити бінарну операцію “+” – як переведення коштів з двох рахунків на третій, при цьому перші два рахунки не закриваються, просто суми на них зводяться до 5, і унарну “--” – як знімання відсотків для депозитного і як операція знімання 5 гривень для розрахункового ( дата – поточна). Функцію print перетворити на віртуальну. Вимоги до готового програмного продукту: 1. В залежності від отриманого завдання вияснити і організувати необхідні класи. 2. Визначити декілька конструкторів. 3. Забезпечити повний набір операцій для кожного з класів. З повагою ІЦ "KURSOVIKS"! |