- •Конспект лекций по объектно-ориентированному программированию
- •Оглавление
- •Литература
- •Концепция объектно-ориентированного программирования
- •Расширение языка c
- •Абстрактные типы данных
- •Дружественные функции
- •Перегрузка операций
- •Производные классы
- •Параметрический полиморфизм
- •Библиотека ввода-вывода iostream.H
Дружественные функции
Иногда желательно, чтобы функция – не член класса, имела доступ к скрытым элементам класса. Это противоречит принципу инкапсуляции данных, поэтому вопрос об использование таких функций спорно. Основная причина использования таких функций состоит в том, что некоторые функции нуждаются в привилегированном доступе более, чем к одному классу. Такие функции получили название дружественных.
Для того, чтобы функция – не член класса имела доступ к private-членам класса, необходимо в определение класса поместить объявление этой дружественной функции, используя ключевое слово friend. Объявление дружественной функции начинается с ключевого слова friend и должно находиться только в определении класса
void func() {...}
class A
{
//..................
friend void func();
//..................
};
Дружественная функция, хотя и объявляется внутри класса (класс A в данном примере), функцией-членом не является. Поэтому не имеет значения, в какой части тела класса (private, public) она объявлена.
Функция-член одного класса может быть дружественной для другого класса
-
class A
{...............
int func();
...............
};
class B
{...............
friend int A :: func();
...............
};
Функция-член (func) класса A является дружественной для класса B
Если все функции-члены одного класса являются дружественными функциями второго класса, то можно объявить дружественный класс
friend class имя_класса;
Например,
class A { ............... }; |
class B {............... friend class A; ............... }; |
Все функции-члены класса А будут иметь доступ к скрытым членам класса В.
В качестве еще одного примера, рассмотрим классы vect – безопасный тип одномерного массива и аналогичный класс matrix – безопасный тип двумерного массива. Допустим, нам необходимо написать функцию умножения вектора на матрицу. Такая функция должна иметь доступ к закрытым членам обоих классов. Это будет функция, дружественная обоим классам. Так как объявление дружественной функции появляется в обоих классах, и в качестве типов аргументов используется каждый класс, необходимо предварительное объявление (прототип) одного из классов перед определением другого. Например класса matrix перед vect:
class matrix; // прототип класса matrix
class vect
{ int *p;
int size;
public:
...............
friend vect mult(const vect &, const matrix &);
...............
};
class matrix
{ int **base;
int column_size, row_size;
public:
...............
friend vect mult(const vect &, const matrix &);
...............
};
vect mult(const vect &v, const matrix &m)
{ int i, j;
if(v.size!=m.column_size) {cout << ”...”; exit();}
vect rez(m.row_size);
for(j=0; j<m,row_size; j++)
{ rez.p[j]=0;
for(i=0; i<m.column_size; i++)
rez.p[i]+=v.p[i]*m.base[i][j];
}
return(rez);
}
