Иногда требуется, чтобы функция – не член класса, имела доступ к скрытым членам класса. Основная причина использования таких функций состоит в том, что некоторые функции нуждаются в привилегированном доступе более, чем к одному классу. Такие функции получили название дружественных.
Для того, чтобы функция – не член класса имела доступ к private-членам класса, необходимо в определение класса поместить объявление этой дружественной функции, используя ключевое слово friend.
Объявление дружественной функции начинается с ключевого слова friend и должно находиться только в определении класса.
class A
{
…
friend void func();
};
Дружественная функция, хотя и объявляется внутри класса, методом класса не является. Поэтому не имеет значения, в какой части тела класса (private, public) она объявлена.
Метод одного класса может быть дружественным для другого класса.
{
…
int func();
};
class B
{
…
friend int A :: func();
};
Метод func() класса A является дружественным для класса B.
Если все методы одного класса являются дружественными для другого класса, то можно объявить дружественный класс:
{
…
};
class B
{
…
friend class A;
};
Все методы класса A будут иметь доступ к скрытым членам класса B.
Пример: Рассмотрим классы
- vect – одномерный массив;
- matrix – двумерный массив.
Необходимо написать функцию умножения вектора на матрицу. Такая функция должна иметь доступ к закрытым членам обоих классов. Это будет функция, дружественная обоим классам.
Так как объявление дружественной функции появляется в обоих классах, и в качестве типов аргументов используется каждый класс, необходимо предварительное объявление (прототип) одного из классов перед определением другого.
Например класса matrix перед vect.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <iostream>
using namespace std;
class matrix; // прототип класса matrix
class vect
{
int* p = NULL;
int size;
public:
vect(int s = 0)
{
size = s;
if (s == 0) return;
p = new int[s];
for (int i = 0; i < s; i++)
p[i] = 0;
}
void in(void)
{
for (int i = 0; i < size; i++)
{
cout << "vect[" << i << "] = ";
cin >> p[i];
}
}
void out(void)
{
cout << "vect: ";
for (int i = 0; i < size; i++)
cout << p[i] << " ";
}
~vect() { delete[] p; } // деструктор
friend vect mult(const vect&, const matrix&);
};
class matrix
{
int** base;
int col_size, row_size;
public:
matrix(int row = 0, int col = 0)
{
base = new int* [row];
for (int i = 0; i < row; i++)
{
base[i] = new int[col];
for (int j = 0; j < col; j++)
base[i][j] = 0;
}
col_size = col;
row_size = row;
}
void in(void)
{
for (int i = 0; i < row_size; i++)
for (int j = 0; j < col_size; j++)
{
cout << "matrix[" << i << "][" << j << "] = ";
cin >> base[i][j];
}
}
void out(void)
{
cout << "matrix: " << endl;
for (int i = 0; i < row_size; i++)
{
for (int j = 0; j < col_size; j++)
cout << base[i][j] << " ";
cout << endl;
}
}
~matrix() // деструктор
{
for (int i = 0; i < row_size; i++)
delete[] base[i];
delete[] base;
}
friend vect mult(const vect&, const matrix&);
};
// Дружественная функция умножения
vect mult(const vect& v, const matrix& m)
{
int i, j;
vect rez(m.col_size);
if (v.size != m.row_size)
{
cout << "No rezult " << endl;
return rez;
}
for (j = 0; j < m.col_size; j++)
{
rez.p[j] = 0;
for (i = 0; i < m.row_size; i++)
rez.p[j] += v.p[i] * m.base[i][j];
}
return rez;
}
int main()
{
matrix m(3, 2);
vect v(3);
v.in();
m.in();
v.out();
cout << endl;
m.out();
vect r = mult(v, m);
r.out();
cin.get(); cin.get();
return 0;
}
Результат выполнения