Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
М.у. объектно-ориентир. прогр. с правкой.doc
Скачиваний:
70
Добавлен:
30.03.2015
Размер:
266.24 Кб
Скачать

Лабораторная работа 5 дружественные функции

Дружественной функцией класса называется функция, которая, не являясь его компонентом, имеет доступ к его защищённым и собственным компонентам. Для реализации прав друга функция должна быть описана в теле класса со спецификатором friend («друг»). Пример класса с дружественной функцией:

# include <conio.h> // консольные функции в текстовом режиме

class charlocus // класс – "символ в заданной позиции экрана"

{

protected:

int x,y; // координаты на экране

char cc; // значение символа связанного с этими координатами

// прототип дружественной функции для замены символа:

friend void frnd_put(charlocus *, char);

public:

charlocus(int xi, int yi, char ci) // конструктор без параметров по умолчанию

{ x = xi;

y = yi;

cc = ci;

}

void display (void) // вывод символа на экран

{ gotoxy(x,y);

putch(cc);

}

};

// описание дружественной функции замены символа в конкретном объекте:

void frnd_put (charlocus *p, char c)

{ p->cc=c; }

void main()

{ charlocus D(20,4,'d'); // создать объект с помощью конструктора

charlocus S(10,10,'s'); // создать объект с помощью конструктора

clrscr(); // обновить устройство вывода

D.display(); // печать "d" в позицию 20,34

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

S.display(); // печать "s" в позицию 10,10

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

frnd_put(&D,'*'); // подмена символа "d" на "*" в объекте D

D.display(); // печать "*" в позицию 20,34

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

frnd_put(&S,'#'); // подмена символа "s" на "#" в объекте S

S.display(); // печать "#" в позицию 10,10

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

}

Программа последовательно выводит на экран d (в позицию 20,4), s (в пози­цию 10,10), * (в позицию 20,4), # (в позицию 10,10).

Функция frnd_put() описана в классе charlocus как дружественная функция и определена обычным образом как глобальная функция (вне класса, без ука­зания его имени, без операции :: и без спецификатора friend). Как дружес­твенная, она получает доступ к защищённым (protected) дан­ным класса и изменяет значение символа того объекта, адрес которого будет передан ей как значение первого параметра.

Функция может быть дружественной по отношению к нескольким классам:

class CL2;

class CL1 friend void ff(CL1,CL2); ...

class CL2 friend void ff(CL1,CL2); ...

Void ff(...) тело функции .

Пример. Пусть дана дружественная функция для двух классов «точка на плоскости» и «прямая на плоскости». Класс «точка на плоскости» включает компонентные данные для задания координат (x, y) точки. Компонентными данными класса «прямая на плоскости» будут коэффи­циенты A,B,C общего уравнения прямой Ax + By + C = 0. Дружественная функция определяет отклонение заданной точки от заданной прямой. Если (a, b) – координаты конкретной точки, то для прямой, в уравнение которой входят коэффициенты A, B, C, отклонение вычисляется как A*a + B*b + C.

#include <iostream.h> // предварительное описание класса

class line2;

class point2 // класс "точка на плоскости"

{ float x, y; // координаты точки на плоскости

public:

point2 (float xn=0, float yn=0) // конструктор

{ x = xn; y = yn; }

friend float uclon (point2, line2);

}; // класс "прямая на плоскости":

class line2

{ float A,B,C; // параметры прямой

public:

line2 (float a, float b, float c) // конструктор

{ A=a; B=b; C=c; }

friend float uclon (point2, line2);

}; // внешнее определение дружественной функции:

float uclon (point2 p, line2 l)

{ return l.A*p.x+l.B*p.y+l.C; }

void main(void)

{ point2 P(16.0,12.3); // определение точки P

line2 L(10.0, -42.3, 24.0); // определение прямой L

cout << "\n Отклонение от точки P до прямой L: ";

cout << uclon(P,L);

}

Дружественные функции не наследуются в производных классах. Отношение friend не является транзитивным, т.е. из двух отношений:

A friend B и B friend C не cледует, что A friend C.