Лабораторна робота № 15 Тема: Друзі класу. Правила визначення та засоби використання. Подружні класи, та функції. Мета: Розглянути та вивчити: друзі классу; правила визначення та засоби використання; подружні класи, та функції. Теоретичні відомості: Нехай визначені два класи: vector (вектор) і matrix (матриця). Кожен з них приховує своє подання, але дає повний набір операцій для роботи з об'єктами його типу. Припустимо, треба визначити функцію, які примножують матрицю на вектор. Для простоти припустимо, що вектор має чотири елементи з індексами від 0 до 3, а в матриці чотири вектора теж з індексами від 0 до 3. Доступ до елементів вектора забезпечується функцією elem (), і аналогічна функція є для матриці. Можна визначити глобальну функцію multiply (помножити) наступним чином: vector multiply (const matrix & m, const vector & v); ( vector r; for (int i = 0; i <3; i + +) (/ / r [i] = m [i] * v; r.elem (i) = 0; for (int j = 0; j <3; j + +) r.elem (i) + = m.elem (i, j) * v.elem (j); ) return r; ) Це цілком природне рішення, але воно може виявитися дуже неефективним. При кожному виклику multiply () функція elem () буде викликатися 4 * (1 +4 * 3) раз. Якщо в elem () проводиться справжній контроль кордонів масиву, то на такий контроль буде витрачено значно більше часу, ніж на виконання самої функції, і в результаті вона виявиться непридатною для користувачів. З іншого боку, якщо elem () є якийсь спеціальний варіант доступу без контролю, то тим самим ми засмічуємо інтерфейс з вектором і матрицею особливою функцією доступу, яка потрібна тільки для обходу контролю. Якщо можна було б зробити multiply членом обох класів vector і matrix, ми могли б обійтися без контролю індексу при зверненні до елемента матриці, але в той же час не вводити спеціальної функції elem (). Проте, функція не може бути членом двох класів. Треба мати на мові можливість впроваджувати нові функції, що не є членом, право доступу до приватних членів класу. Функція - не член класу, - що має доступ до його закритої частини, називається одним цього класу. Функція може стати другом класу, якщо в його описі вона описана як friend (друг). Наприклад: class matrix; class vector ( float v [4]; / / ... friend vector multiply (const matrix &, const vector &); ); class matrix ( vector v [4]; / / ... friend vector multiply (const matrix &, const vector &); ); Функція-друг не має ніяких особливостей, за винятком права доступу до закритої частини класу. Зокрема, в такій функції не можна використовувати вказівник this, якщо тільки вона дійсно не є членом класу. Опис friend є справжнім описом. Воно вводить ім'я функції в область видимості класу, в якому вона була описана, і при цьому відбуваються звичайні перевірки на наявність інших описів такого ж імені в цій області видимості. Опис friend може знаходиться як у загальній, так і в приватному частинах класу, це не має значення. Тепер можна написати функцію multiply, використовуючи елементи вектора і матриці безпосередньо: vector multiply (const matrix & m, const vector & v) ( vector r; for (int i = 0; i <3; i + +) (/ / r [i] = m [i] * v; r.v [i] = 0; for (int j = 0; j <3; j + +) r.v [i] + = m.v [i] [j] * v.v [j]; ) return r; ) Відзначимо, що подібно до функції-члену дружня функція явно описується в описі класу, з яким дружить. Тому вона є невід'ємною частиною інтерфейсу класу нарівні з функцією-членом. Функція-член одного класу може бути другом іншого класу: class x ( / / ... void f (); ); class y ( / / ... friend void x:: f (); ); Цілком можливо, що всі функції одного класу є друзями іншого класу. Для цього є коротка форма запису: class x ( friend class y; / / ... ); У результаті такого опису всі функції-члени y стають друзями класу x. Хід роботи Використання друзів класу в наступних структурах: «Спорт клубу». «Бібліотеки». «Обувного магазину» «Булочної» «Мобільного магазину» Тощо…