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).