    Функция Show() объявлена с двумя ссылочными параметрами cl и с2 двух типов 
классов. Поскольку функция Show() дружественна обоим классам, операторы внутри 
Show() имеют доступ к защищенным и закрытым членам объектов классов-аргументов, 
переданных функции. 
    Например, в реализации функции Show() (строки 30-33) отображаются значения 
строк, адресованных указателями si и s2. Поскольку функция Show() дружественна 
обоим классам, она может ссылаться непосредственно на данные-члены si и s2, 
закрытые в своих классах. Другие "недружественные" функции не имеют такого 
доступа к скрытым членам этих классов. 

    Дружественные функции-члены 

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

    Листинг 15.3.  FRIEfJDMF.CPP (использование дружественных функций-членов) 

    1:	#include <iostream.h> 
    2: 
    3:	class One;  //	Неполное объявление класса 
    4: 
    5:	class Two { 
    6:	private: 
    7:	  char *s2; //	Доступен членам класса Two 
    8:	public: 
    9:	  Two() { s2 =	"one, two, three"; } 
    10:	  void Show(0ne &c1); 
    11:	}; 
    12: 
    13:	class One { 
    14:	   friend void Two: :Show(One &c1); 
    15:	private: 
    16:	   char *s1; //	Доступен в классе One и в Two:: Show 
    17;	public: 
    18:	   One() { s1 =	"Testing "; } 
    19:	}; 
    20: 
    21:	main() 
    22:	{ 
    23:	One c1; 
    24:	Two c2; 
    25: 
    26:	c2.Show(c1); 
    27:	return 0; 
    28:	} 
    29: 
    30:	void Two: :Show(One &d) 
    31:	{ 
    32:	  cout « c1.s1 « s2 « '\n'; 
    33:	} 

    Как и в модуле FRIENDFN (листинг 15.2), в новой программе FRIENDMF 
объявляется два класса, One и Two. В классе One объявляется аналогичная 
дружественная функция-член (строка 14) с помощью имени класса и оператора 
разрешения области видимости (Two::), чтобы указать компилятору 
местонахождение функции Show(). 
    Порядок объявления двух классов изменился по сравнению с приведенным в 
предыдущем листинге на обратный, поскольку класс, в котором содержится 
прототип функции-члена, должен объявляться до класса, указывающего функцию-член 
дружественной. Для класса One, объявляющего дружественной функцию Two::Show(), 
объявление класса Two уже должно быть доступно компилятору. 
    Еще одно отличие состоит в способе доступа к закрытым данным обоих классов 
в функции ShowO (строки 30—33). Объявлен только один ссылочный параметр One &cl. 
Поскольку функция Show() — член класса Two, она имеет непосредственный 
доступ ко всем членам класса Two. Выражение c1.s1 в операторе вывода в поток 
в строке 32 не является недозволенным, так как функция Show() дружественна классу 
One, которому принадлежит закрытый член s1. Функция-член ShowO может ссылаться 
на s2 непосредственно, поскольку этот член принадлежит классу Two, в котором 
объявлена Show(). 
    Поскольку функция Show() — член класса Two, в ней определен указатель this, 
ссылающийся на объект класса, для которого была вызвана функция-член. Поэтому в 
программе должен объявляться объект класса Two (строка 24), затем вызываться 
функция Show() для этого объекта (строка 26). 


    15. Передовые средства C++     371 
