2. Приятелски
функции
Приятелската функция не е член-функция на класа, но тя има
достъп до private членовете
на класа. Приятелски функции се използват, когато е
необходимо една функция да има достъп до private членовете
на два или повече различни класа.
Декларацията на приятелската
функция може да се намира както в частта public, така и в частта private и се
характеризира с ключовата дума friend, която се поставя в началото на декларацията. Една
приятелска функция се дефинира като обикновена функция, която не е член на
клас.
1.1. Независима функция – приятелска за
два или повече класа.
Тази
функция трябва да се декларира във всеки от класовете като приятелска.
Приятелските
функции не са член-функции на класа и затова те не получават като първи
параметър по неявен начин this. Поради тази причина е необходимо подаването на обект
по явен начин като параметър на функцията.
friend int
sp_greater(car c, truck t);
Извикването
на приятелска функция се извършва чрез името на функцията и списък от
фактически параметри:
sp_greater(c1, t1);
Задача 1. Следната програма създава клас car и клас truck, всеки
от които съдържа private променлива, която определя скоростта на превозното
средство. Тази програма съдържа функцията sp_greater(), която е
приятелска функция и на car и на truck.
#include <iostream.h>
class truck; //Предварителна декларация
class car {
int
passengers;
int
speed;
public:
car(int p, int s) { passengers = p;
speed = s; }
friend int sp_greater(car c, truck t);
};
class truck {
int weight;
int speed;
public:
truck(int w, int s) { weight = w; speed
= s;}
friend int sp_greater(car c, truck t);
};
/* Връща положителна стойност, ако скоростта на колата е
по-голяма от тази на камиона. Връща 0, ако скоростите са еднакви. Връща
отрицателна стойност, ако скоростта на камиона е по-голяма от тази на колата.
*/
int sp_greater(car c, truck t)
{
return c.speed - t.speed;
}
int main()
{
int t;
car c1(6, 55), c2(2, 120);
truck t1(10000, 55),
t2(20000, 72);
cout << ”Comparing c1 and t1:\n”;
t = sp_greater(c1, t1);
if(t<0) cout << ”Truck is faster.\n”;
else if(t==0)
cout << ”Car and truck speed is the same.\n”;
else cout
<< ”Car is faster.\n”;
cout << ”\nComparing c2 and t2:\n”;
t = sp_greater(c2, t2);
if(t<0) cout << ”Truck is faster.\n”;
else if(t==0)
cout << ”Car and truck speed is the same.\n”;
else cout
<< ”Car is faster.\n”;
return 0;
}
Тъй като sp_greater() приема параметри едновременно от класовете car и
truck, то е невъзможно да се декларират и двата класа,
преди sp_greater() да
бъде включена в тях. За да се укаже на С++ компилатора, че даден идентификатор
представлява име на клас, се използва предварителна декларация:
class truck;
1.2. Член-функцията на един клас –
приятелска за друг клас.
При декларирането на приятелската функция трябва да се
прецизира класът, на който тя е член-функция с помощта на оператор за
принадлежност(::).
Задача 2. Предния пример, написан така, че sp_greater() да е член-функция на car и приятелска функция на truck, ще изглежда по следния начин:
#include <iostream.h>
class truck; //Предварителна декларация
class car {
int
passengers;
int
speed;
public:
car(int p, int s) { passengers = p;
speed = s;}
int
sp_greater(truck t);
};
class truck {
int weight;
int speed;
public:
truck(int w, int s) { weight = w; speed
= s;}
friend int car::sp_greater(truck t);
};
/* Връща положителна стойност, ако скоростта на колата е
по-голяма от тази на камиона. Връща 0, ако скоростите са еднакви. Връща
отрицателна стойност, ако скоростта на камиона е по-голяма от тази на колата.
*/
int car::sp_greater(truck t)
{
return speed - t.speed; // Тъй като sp_greater() е член на car, то трябва да се подаде само
} // обектът за камион
int main()
{
int t;
car c1(6, 55), c2(2, 120);
truck t1(10000, 55), t2(20000,
72);
cout << ”Comparing c1 and t1:\n”;
t = c1.sp_greater(t1); //Извиква
се като член-функция на car
if(t<0) cout << ”Truck is faster.\n”;
else if(t==0)
cout << ”Car and truck speed is the same.\n”;
else cout
<< ”Car is faster.\n”;
cout << ”\nComparing c2 and t2:\n”;
t = c2.sp_greater(t2); //Извиква
се като член-функция на car
if(t<0) cout << ”Truck is faster.\n”;
else if(t==0)
cout << ”Car and truck speed is the same.\n”;
else cout
<< ”Car is faster.\n”;
return 0;
}
В този случай се използва оператора за принадлежност(::) в декларацията на приятелската
функция в класа truck, за да укаже
на компилатора, че функцията sp_greater() е член на класа car.
Задачи за самостоятелна работа:
Разширете функционалността на задачи 1 и 2, като
имплементирате друга приятелска функция, която да изчислява времето за
изминаване на зададени километри (S =
V * T).