Друзья.
7.1 Дружественные классы.
Методы могут быть превращены в дружественные функции одновременно с определением всего класса как дружественного.
Допустим для класса «А», весь класс «Б» провозглашен дружественным. Тогда все методы класса «В» имеют доступ к скрытым данным класса «А».
Для того чтобы организовать такую конструкцию, необходимо использовать следующее выражение:
friend class В
А можно было сделать и так: сначала объявить обычный класс «В»:
class В;
затем объявить класс «А», а внутри определения «А» объявить дружественность класса «В»:
friend B;
Рассмотрим пример с использованием дружественных классов.
Пример 16:
#include <iostream>
using namespace std;
class A;
class B
{
private:
int i1;
friend class A;
public:
void vvod()
{
cout<<"Vvedite 4islo i1\n";
cin>>i1;
}
};
class A
{
protected:
int i2;
public:
void func(B obj)
{
int i;
obj.vvod();
cout<<"Vvedite 4islo i2\n";
cin>>i2;
i=i2+obj.i1;
cout<<"\nOtvet"<<i;
}
};
int main()
{ A a;
B b;
a.func(b);
return 0;
}
Представьте, что вам необходимо, чтобы функция работала с объектами двух разных классов. Например, функция будет рассматривать объекты двух классов как аргументы, и обрабатывать их скрытые данные. В такой ситуации ничто не спасет, кроме friend -функции.
|
|
Предположим, у нас имеются всё те же два класса «А» и «В». Нам необходимо, чтобы некоторая функция func() имела доступ и к тем, и к другим скрытым данным, поэтому мы делаем ее дружественной функцией. Этой цели в объявлениях внутри каждого класса служит ключевое слово friend:
friend int func(A, B)
Это объявление может быть расположено где угодно внутри класса. Нет никакой разницы, запишем мы его в public или private - секцию.
Объект каждого класса передается как параметр функции func(), и функция имеет доступ к скрытым данным обоих классов посредством этих аргументов.
Напоминаем, что к классу нельзя обращаться до того, как он не объявлен в программе.
Рассмотрим пример, дающий представление о работе дружественных функций в качестве мостов между двумя классами.
Пример 17:
#include <iostream>
using std::cout;
using std::endl;
class Count
{
friend void setX(Count &, int); // friend declaration
public:
// constructor
Count()
: x(0) // initialize x to 0
{
// empty body
} // end constructor Count
// output x
void print() const
{
cout << x << endl;
} // end function print
private:
int x; // data member
}; // end class Count
// function setX can modify private data of Count
// because setX is declared as a friend of Count (line 10)
void setX(Count &c, int val)
{
c.x = val; // allowed because setX is a friend of Count
} // end function setX
int main()
{
Count counter; // create Count object
cout << "counter.x after instantiation: ";
counter.print();
setX(counter, 8); // set x using a friend function
cout << "counter.x after call to setX friend function: ";
counter.print();
return 0;
}