Дружні функції і дружні класи
Працюючи з дружніми функціями, потрібно враховувати наступні обмеження. У ході виконання цієї програми на екрані з’являться наступні рядки. Наприклад, попередню програму можна переробити в такий спосіб. Void print (TNumber z); // Апеляція до не цілком оголошеного класу. У результаті одержуємо наступні повідомлення. Вони не можуть мати специфікатори static і extern. Friend class TFunction… Читати ще >
Дружні функції і дружні класи (реферат, курсова, диплом, контрольна)
Використання дружніх функцій.
#include.
class TComplex.
{.
friend TComplex sum (TComplex, TComplex);
double Re;
double Im;
public:
static int counter;
TComplex (double x, double y):Re (x), Im (y).
{ counter++;printf («Ctor %d «, counter);}.
TComplex (TComplex& z).
{ Re = z. Re; Im = z. Im; counter++; printf («Copy %d «, counter);}.
~TComplex (){printf («Dtor %d «, counter);counter—;}.
void print () {printf («Z = %lf + i*%lf «, Re, Im);}.
};
TComplex sum (TComplex, TComplex);
int TComplex: counter = 0;
int main ().
{.
printf («Start main «);
TComplex z (1,1), w (2,2), u (0,0);
u = sum (z, w);
printf («End sum «);
u.print ();
printf («End main «);
return 0;
}.
TComplex sum (TComplex u, TComplex v).
{.
printf («Start «);
TComplex w (0,0);
w.Re= u. Re + v. Re;
w.Im=u.Im + v. Im;
return w;
}.
Дружня функція має всі права члена класу. Отже, їй доступні всі поля — як відкриті, так і закриті. Для того щоб оголосити функцію дружньої, ключове слово friend слід помістити в оголошення класу. (Клас сам оголошує своїх друзів!).
Розділимо клас TComplex на два: TNumber і TFunction. У першому класі залишимо змінні-члени, а до другого віднесемо усі функції.
Використання дружніх функцій-членів.
#include.
class TNumber;
class TFunction.
{.
public:
void print (TNumber z);
};
class TNumber.
{.
double Re;
double Im;
public:
static int counter;
TNumber (double x, double y):Re (x), Im (y).
{ counter++;printf («Ctor %d «, counter);}.
TNumber (TNumber& z).
{ Re = z. Re; Im = z. Im; counter++; printf («Copy %d «, counter);}.
~TNumber (){printf («Dtor %d «, counter);counter—;}.
friend void TFunction: print (TNumber);
};
int TNumber: counter = 0;
int main ().
{.
printf («Start main «);
TNumber z (1,1);
TFunction a;
a.print (z);
printf («End main «);
return 0;
}.
void TFunction: print (TNumber z).
{.
printf («z = %lf + i*%lf «, z. Re, z. Im);
}.
У результаті одержуємо наступні повідомлення.
Start main.
Ctor 1.
Copy 2.
z = 1.0 + i*1.0.
Dtor 2.
End main.
Dtor 1.
Зверніть увагу на те, що функція print (), що належить класу TFunction, одержує параметр типу.
TNumber. Отже, цей тип повинний бути визначений раніше. Однак клас TNumber оголошує дружню функцію print (), що належить класу TFunction. Для розв’язання цієї проблеми в мові С++ передбачений механізм неповного оголошення класу.
Працюючи з дружніми функціями, потрібно враховувати наступні обмеження.
- 1. Вони не успадковуються.
- 2. Вони не можуть мати специфікатори static і extern.
- 3. У класі, функція-член якого є дружньою до не цілком оголошеного класу, слід розміщати тільки прототип. Реалізація функції повинна знаходитися після повного оголошення класу.
Коли усі функції деякого класу є дружніми стосовно іншого класу, можна оголосити весь клас дружнім.
Наприклад, попередню програму можна переробити в такий спосіб.
Використання дружніх класів.
#include.
class TNumber; // Неповне оголошення.
TFunction.
{.
public:
void print (TNumber z); // Апеляція до не цілком оголошеного класу.
};
class TNumber.
{.
double Re;
double Im;
public:
static int counter;
TNumber (double x, double y):Re (x), Im (y).
{ counter++;printf («Ctor %d «, counter);}.
TNumber (TNumber& z).
{ Re = z. Re; Im = z. Im; counter++; printf («Copy %d «, counter);}.
~TNumber (){printf («Dtor %d «, counter);counter—;}.
friend class TFunction; // Оголошення дружнього класу.
};
int TNumber: counter = 0;
int main ().
{.
printf («Start main «);
TNumber z (1,1);
TFunction a;
a.print (z);
printf («End main «);
return 0;
}.
void TFunction: print (TNumber z).
{.
printf («z = %lf + i*%lf «, z. Re, z. Im);
}.
Варто мати на увазі, що члени класу TFunction просто мають доступ до членів класу TNumber, але члени класу TNumber від цього не стають членами класу TFunction.
Іноді два класи настільки тісно зв’язані, що їм необхідний повний доступ до всіх членів. У цьому випадку їх оголошують взаємно дружніми.
Використання взаємно дружних класів.
#include
class TNumber;
class TFunction.
{.
void print (TNumber z);
friend class TNumber;
};
class TNumber.
{.
double Re;
double Im;
public:
static int counter;
TNumber (double x, double y):Re (x), Im (y).
{ counter++;printf («Ctor %d «, counter);}.
TNumber (TNumber& z).
{ Re = z. Re; Im = z. Im; counter++; printf («Copy %d «, counter);}.
~TNumber (){printf («Dtor %d «, counter);counter—;}.
void sum (TNumber y, TFunction z).
{Re = Re + y. Re; Im = Im + y. Im; z. print (*this);}.
friend class TFunction;
};
int TNumber: counter = 0;
int main ().
{.
printf («Start main «);
TNumber z (1,1), x (1,1);
TFunction a;
z.sum (z, a);
printf («End main «);
return 0;
}.
void TFunction: print (TNumber z).
{.
printf («z = %lf + i*%lf «, z. Re, z. Im);
}.
У ході виконання цієї програми на екрані з’являться наступні рядки.
Start main.
Ctor 1.
Ctor 2.
Copy 3.
Copy 4.
z = 2.0 + i*2.0.
Dtor 4.
Dtor 3.
End main.
Dtor 2.
Dtor 1.
Як бачимо, функція sum (), що є членом класу TNumber, одержує вільний доступ до функції print (), оголошеної в закритому розділі класу TFunction. Якби класи TNumber і TFunction не були взаємно дружніми, це було б неможливо.