- •Объектно-ориентированное программирование.
- •Методические указания к лабораторным работам Омск 2007
- •Лабораторная работа 1
- •Задания к лабораторной работе 1
- •Лабораторная работа 2 конструкторы и деструкторы
- •Задания к лабораторной работе 2
- •Лабораторная работа 3 наследование
- •Задания к лабораторной работе 3
- •Лабораторная работа 4 полиморфизм. Перегрузка операций и функций
- •Задания к лабораторной работе 4
- •Лабораторная работа 5 дружественные функции
- •Void ff(...) тело функции .
- •Задания к лабораторной работе 5
- •Библиографический список
- •Содержание
Лабораторная работа 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.