Объектно-ориентированное программирование — Дружественные классы

Дружественные классы

Напомним, что для того, чтобы функция, определенная обычным образом, получила доступ ко всем членам класса, включая закрытые, ее следует объявить дружественной, указав в теле класса ее прототип с ключевым словом friend. Функцией, дружественной классу, может быть как произвольная внешняя функция, так и составная функция другого класса, который должен быть уже определен. Например, если мы хотим перегрузить операцию вывода на экран элементов двумерного массива, определенного выше классом twomas, то нам будет нужен доступ к закрытым членам класса. Для обеспечения этого доступа в теле класса следует объявить прототип функции

friend ostream& operator << (ostream& o, twomas& d);

и определить операцию вывода с помощью внешней подпрограммы (функции):

ostream& operator << (ostream& o, twomas& d)

{

int i, j;

for(i = 1; i <= d.n; i++)

{

for(j = 1; j <= d.n; j++)

o << d(i, j) << ‘ ‘;

o << “\n”;

}

return o;

}

Если класс содержит объекты другого класса в качестве полей, то его составным функциям необходим дополнительный доступ к закрытым членам этих полей. Например, в классе вектора, состоящего из n комплексных чисел

class Vectorc

{

Complex *z;

Public:

double norma();

};

составная функция norma(), возвращающая максимум абсолютных величин вещественных и мнимых компонент вектора, не имеет доступа к этим компонентам. Чтобы обеспечить этот доступ, в классе Complex следует указать функцию Vectorc::norma() как дружественную. Поскольку к моменту объявления составной функции класс

Vectorc должен быть определен, то следует указать перед определением класса Complex этот класс Vectorc как внешний (глобальный):

class Vectorc;

class Complex

{

double Re, Im;

friend double Vectorc::norma();

};

а затем определить класс Vectorc.

Существует возможность сделать доступными все члены класса А для каждой из составных функций класса В. Для реализации этой возможности достаточно класс B объявить дружественным для класса А. К моменту объявления класс B должен быть определен или объявлен как внешний. Члены класса А не становятся доступными для дружественных функций класса B.

Пример. Определим класс графического окна, в которое будет выводиться график линейной функции. Линейная функция определяется как класс.

#include

#include

class Wnd; // Прототип класса Wnd

// Класс — функция

class Func

{

// Закрытые элементы

double k, b; // y = kx + b

friend class Wnd; // Объявление дружественного класса

public: // Общедоступные элементы

Func(double k1, double b1=0): k(k1), b(b1) {} // Конструктор

};

// Класс окна

class Wnd

{

// Закрытые элементы

int xleft, xright, ytop, ybot; // Реальные координаты окна

double xmin, ymin, xmax, ymax; // Относительные координаты окна

public: // Общедоступные элементы

// Конструктор

Wnd(double x0, double y0, double x1, double y1,

int xl=0, int yt=0, int xr=639, int yb=479):

xmin(x0), ymin(y0), xmax(x1), ymax(y1),

xleft(xl), ytop(yt), xright(xr), ybot(yb) {}

Wnd& operator << (Func); // Перегрузка операции <<

};

// Перегрузка операции <<

Wnd& Wnd::operator << (Func f)

{

double xkof, ykof; // Коэффициенты перевода относительных

// координат в реальные

xkof = (xright-xleft)/(xmax-xmin);

ykof = (ybot-ytop)/(ymax-ymin);

rectangle(xleft, ytop, xright, ybot); // Рамка

line(xleft,

ytop+(ymax-ymin)*ykof/2,

xright,

ytop+(ymax-ymin)*ykof/2); // Ось х

line(xleft+(xmax-xmin)*xkof/2,

ytop,

xleft+(xmax-xmin)*xkof/2,

ybot); // Ось у

line((xright — xleft)/2 + xmin*xkof,

(ybot — ytop)/2 — (xmin*f.k+f.b)*ykof,

(xright — xleft)/2 + xmax*xkof,

(ybot — ytop)/2 — (xmax*f.k+f.b)*ykof); // Вывод функции

return (*this);

}

void main()

{

int gd=DETECT, gm;

Wnd w(-5, -3, 5, 3); // Определение окна

Func phi(1, 1); // Определение функции

initgraph(&gd, &gm, ""); // Инициализация графики

w<

getch(); // Ожидание нажатия клавиши

closegraph(); // Закрытие графики

}

Результаты работы программы

clip_image006

Вы здесь: Главная Информатика Программирование Объектно-ориентированное программирование