Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
7
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

19.3.2. Використання функцій-"друзів" класу для перевантаження операторів виведення даних

У попередній програмі операторна функція виведення даних не була визначена як член класу kooClass. Насправді ні будь-яка операторна функція виведення даних, ні функція їх введення не можуть бути членами класу. Справа тут полягає ось в чому. Якщо операторна функція є членом класу, то лівий операнд (що опосередковано передається за допомогою покажчика this) повинен бути об'єктом класу, який генерує звернення до цієї операторної функції. І це змінити не можна. Проте під час перевантаження операторів виведення даних лівий операнд повинен бути потоком, а правий – об'єктом класу, дані якого підлягають виведенню. Отже, перевантажені оператори виведення даних не можуть бути функціями-членами класу.

У зв'язку з тим, що операторні функції виведення даних не можуть бути членами класу, для якого вони визначаються, то виникає серйозне запитання: як перевантажений оператор виведення даних може отримати доступ до закритих членів класу? У попередній програмі (див. код програми 19.1) змінні х, y і z були визначені як відкриті, тому оператор виведення даних без перешкод міг отримати до них доступ. Водночас закриття даних – важлива частина об'єктно-орієнтованого програмування, то вимагати, щоб усі дані були відкритими, просто нелогічно. Проте існує просте вирішення цього питання – оператор виведення даних можна зробити "другом" класу. Якщо функція є "другом" деякого класу, то вона отримує легальний доступ до його private-даних. Оголошення "другом" класу операторної функції виведення даних продемонструємо на прикладі класу kooClass.

Код програми 19.2. Демонстрація механізму використання функцій-"друзів" класу для перевантаження оператора виведення даних

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

class kooClass { // Оголошення класового типу

int x, y, z; // Тривимірні координати (тепер це private-члени)

public:

kooClass(int a, int b, int c) { x = a; y = b; z = c;}

friend ostream &operator<<(ostream &stream, kooClass obj);

};

// Відображення тривимірних координат x, y, z

// Перевантажений оператор виведення даних для класу kooClass

ostream &operator<<(ostream &stream, kooClass obj)

{

stream << obj.x << ", ";

stream << obj.y << ", ";

stream << obj.z << "\n";

return stream; // Повертає посилання на параметр stream

}

int main()

{

kooClass A_ob(1, 2, 3), B_ob(3, 4, 5), C_ob(5, 6, 7);

// Перевантажений оператор виведення даних

cout << A_ob << B_ob << C_ob;

getch(); return 0;

}

Звернемо Вашу увагу на те, що змінні х, y і z у цій версії програми є закритими у класі kooClass, проте, операторна функція виведення даних звертається до них безпосередньо. У наведеному прикладі якраз і виявляється велика перевага "друзів" класу: оголошуючи операторні функції введення та виведення даних "друзями" класу, для якого вони визначаються, ми тим самим підтримуємо принцип інкапсуляції об'єктно-орієнтованого програмування.