Дружественные функции и классы
Объявление дружественной функции начинается с ключевого слова friend и должно находиться только в определении класса:
Пример дружественной функции
Среднее арифметическое четных чисел, оканчивающихся на 6
Дружественная функция, хотя и объявляется внутри класса (класс B в данном примере), функцией-членом не является. Поэтому не
Продолжение программы
Определение дружественных функций в классе
Продолжение примера
Окончание примера
Дружественный класс
Дружественный класс
Пример с дружественным классом
Продолжение примера
Продолжение программы
Окончание программы
734.50K
Category: programmingprogramming

Лекция 3 Дружественные функции и классы

1. Дружественные функции и классы

Васильева Лидия Николаевна
доцент кафедры автоматики и управления
в технических системах

2.

Определение дружественной функции
Дружественные функции не являются
членами класса, но имеют доступ к
его закрытым элементам.
Определяется как обычные функции.
В объявление класса, для которого она
будет дружественной, необходимо
включить прототип, перед которым
поместить friend.

3. Объявление дружественной функции начинается с ключевого слова friend и должно находиться только в определении класса:

4. Пример дружественной функции

#include <iostream>
using namespace std;
class samp {
int s[10];
public:
void show() {for (int i=0;i<10;i++) cout << s[i] << "\n"; }
void set() { int a; for (int i=0;i<10;i++) {cin>>a; s[i]=a;} }
friend int f (samp ob);
};
int f (samp ob)
{ int sum=0, i;
for (i=0; i<10; i++)
if (ob.s[i]>0) sum++; return sum;}
int main()
{samp ob;
int i; ob.set();
cout<<"\n kol-vo "<<f(ob)<<endl;
ob.show();
return 0;}

5. Среднее арифметическое четных чисел, оканчивающихся на 6

#include <iostream>
using namespace std;
class samp {
int s[10];
public:
void show() {for (int i=0;i<10;i++) cout << s[i] << "\n"; }
void set() { int a; for (int i=0;i<10;i++) {cin>>a; s[i]=a;} }
friend int f (samp ob);};
float f (samp ob)
{ float sum=0, i, b=0;
for (i=0; i<10; i++)
if (ob.s[i]%2==0&&ob.s[i]%10==6) {b++;sum+=ob.s[i];}
return sum/b;}
int main()
{samp ob;
int i; ob.set();
cout<<"\n sr. ar. = "<<f(ob)<<endl;
ob.show();
return 0;}

6. Дружественная функция, хотя и объявляется внутри класса (класс B в данном примере), функцией-членом не является. Поэтому не

имеет
значения, в какой части тела класса (private,
public) она объявлена.
Функция-член одного класса может быть
дружественной для другого класса

7.

Дружественная функция вызывается как обычная
функция. Доступ к закрытым элементам класса она
может получить только через объект класса. Такая
функция не наследуется.
Функция может быть дружественной более чем к
одному классу. В этом случае функция получает
параметры от нескольких классов и невозможно
объявить все классы перед включением функции
в каждый из них. Чтобы сообщить компилятору,
что данный идентификатор является именем
класса, перед первым использованием имени
класса размещают предварительное объявление:
class имя_класса;

8.

Функция дружественная к двум классам
// Программа сравнивает площади
#include <iostream>
#include <cmath>
using namespace std;
class pr; // предварительное объявление
class tr {
int a,b,c;
float s;
public:
tr(int x, int y, int z) { a = x; b = y; c=z; }
void set_s(){float p=0.5*(a+b+c);
s=sqrt(p*(p-a)*(p-b)*(p-c));}
float get_s(){ return s;}
friend float f(tr c, pr t) ;
};

9. Продолжение программы

class pr {
int a,b;
float s;
public:
pr(int x, int y) { a = x; b = y; }
void set_s(){s=a*b;}
float get_s(){ return s;}
friend float f(tr c, pr t) ;
};
float f(tr c, pr t)
{ c.set_s(); cout<<"s tr="<<c.get_s()<<endl;
t.set_s(); cout<<"s pr="<<t.get_s()<<endl;
return c.s - t.s;
}

10.

Окончание программы
int main()
{float t;
tr t1(3, 5, 4), t2 (2, 2, 2) ;
pr p1(3, 2), p2(2, 1);
cout<< " t1 and pl:\n";t = f(t1, p1);
if(t<0) cout << " S tr-ka <\n";
else if (t==0) cout << "Ravny\n";
else cout << "S pr-ka < \n";
cout<< " t2 and p2:\n";
t = f(t2, p2); if(t<0) cout << " S tr-ka <\n";
else if (t==0) cout << "Ravny\n";
else cout << "S pr-ka < \n";
return 0;
}

11. Определение дружественных функций в классе

Класс Person использует объект класса Auto:
#include <iostream>
using namespace std;
class Auto; // объявление класса Auto
class Person {//класс человек
public:
Person(string p_name) {
name = p_name;}
void drive(const Auto&);
void setPrice(Auto&, unsigned);
private:
string name;
};

12. Продолжение примера

class Auto{
friend void Person::drive(const Auto&);
friend void Person::setPrice(Auto&, unsigned);
public:
Auto(string a_name, unsigned a_price) {
name = a_name;
price = a_price;
}
void print() {
cout << name << ": " << price << endl;
private:
string name;
unsigned price;
};

13. Окончание примера

void Person::drive(constAuto &car){
cout<< name << " drives " <<car.name<< endl;
}
void Person::setPrice(Auto &car, unsigned price){
car.price= price;
}
int main() {
Auto a{"Lada", 5000};
Person t{"Maks"};
t.drive(a);
t.setPrice(a, 8000);
tesla.print();
}

14. Дружественный класс

В случае если один класс активно использует
объекты другого, целесообразно определять не
отдельные дружественные функции, а определить
дружественным весь класс.

15. Дружественный класс

Все функции-члены класса А будут иметь доступ к скрытым членам
класса В.
Дружба классов не транзитивна: если X является другом класса Y,
а Y - другом класса Z, это еще не означает, что X является другом
класса Z.

16. Пример с дружественным классом

#include <iostream>
using namespace std;
class Auto;
class Person{
public:
Person(string p_name)
{name = p_name;}
void drive(const Auto&);
void setPrice(Auto&, unsigned);
private:
string name;
};
class Auto {
friend class Person;//дружественный класс
public:
Auto(string a_name, unsigned a_price){
name = a_name;
price = a_price;
}
void print() {
cout << name << " : " << price << endl;
}
private:
string name; // название автомобиля
unsigned price; // цена автомобиля
};

17. Продолжение примера

void Person::drive(const Auto& car) {
cout << name << " drives " << car.name << endl;
}
void Person::setPrice(Auto& car, unsigned price) {
car.price = price;
}
int main() {
Auto tesla{"Tesla", 5000};
Person tom{"Tom"};
tom.drive(tesla);
tom.setPrice(tesla, 8000);
tesla.print();
}

18.

Функция может быть членом одного класса и
дружественной другому
#include <iostream>
#include <cmath>
using namespace std;
class pr; // предварительное объявление
class tr {
int a,b,c;
float s;
public:
tr(int x, int y, int z) { a = x; b = y; c=z; }
float f(pr t);
};

19. Продолжение программы

class pr {
int a,b;
float s;
public:
pr(int x, int y) { a = x; b = y; }
void set_s(){s=a*b;}
float get_s(){ return s;}
friend float tr::f(pr t);//новое использование ::
};
float tr::f(pr t)
{float p=0.5*(a+b+c);
s=sqrt(p*(p-a)*(p-b)*(p-c));
cout<<"s tr="<<s<<endl;
t.set_s(); cout<<"s pr="<<t.get_s()<<endl;
return s - t.s;}

20. Окончание программы

int main()
{float t;
tr t1(3, 5, 4), t2 (2, 2, 2) ;
pr p1(3, 2), p2(2, 1);
cout<< " t1 and p1:\n";t = t1.f(p1);
if(t<0) cout << " S tr-ka <\n";
else if (t==0) cout << "Ravny\n";
else cout << "S pr-ka < \n";
cout<< " t2 and p2:\n";
t = t2.f(p2); if(t<0) cout << " S tr-ka <\n";
else if (t==0) cout << "Ravny\n";
else cout << "S pr-ka < \n";
return 0;
}
English     Русский Rules