    9:	void PutX( int xx )	{ x = xx;   }                                       
    10:	void PutY(int yy)	{ y = yy; }                                                                                                   
    11:	int GetX(void)	{ return x;  }                                         
    12:	int GetY(void)	{return y;   }                                        
    13:	friend ostream& operator«(ostream& os, TPoint &p);                     
    14:	}	; 
    15:				
    16:	main()                                                                 
    17:	{ 
    18:	TPoint p;		
    19:				
    20:	 cout « p « '\n' ;
    21:	p.PutX(I00); 
    22:	p:PutY(200); 
    23:	cout « p « '\n';
    24:	return 0; 
    25:	} 
    26: 
    27:	ostream& operator«(ostream& os, TPoint &p)                                                                                                   | 
    28:	{ 
    29:	  os « "x == " « p.x « ",  у == " « p. у;                               
    30:	  return os; 
    31:	} 

    В строке 13 путем объявления дружественной функции-члена operator«()
перегружается оператор вывода в поток.Эта дружественная функция-член возвращает 
значения типа ostream&, и в ней объявлены два параметра — os типа ostream& и 
ссылка р на объект класса TPoint. 
    Поскольку функция operator«() — друг класса TPoint, оператор в строке 29 
имеет непосредственый доступ к данным-членам х и у объекта, на который 
ссылается ссылка р. Обратите внимание, что всю строку занимает один оператор 
вывода в поток, выводящий через ссылку os типа ostream значения двух 
данных-членов плюс две символьные строки. В конце концов, функция возвращает 
ссылку os. Запуск программы на выполнение приведет к следующим результатам:	

    х == 0,  у == 0 х == 100,  у == 200 

    Поскольку функция operator«() возвращает ссылку на ostream, можно выводить 
несколько объектов в одном операторе вывода в поток. Например, если p1, р2 и 
рЗ — объекты класса TPoint, вы можете отобразить их значения следующим образом: 

    cout « р1 « ";   " « р2 « ";   " « рЗ; 

    На самом деле зги операторы выполняются путем обращения к нескольким 
функциям, реализующим перегрузку оператора вывода в поток. Предыдущая строка 
выполняется подобно написанной следующим образом: 

    ((((cout « р1) « ";   ") « р2) « ";   ") « рЗ; 

    Разве вы не радуетесь тому, что вам не надо вводить все эти скобки? 
    
    Перегрузка оператора ввода из потока 

    Также возможна и перегрузка оператора ввода из потока », с ее помощью 
можно научить C++ читать из потока объекты класса. В листинге 15.9 к 
возможностям программы-примера POINTOUT.CPP из предыдущего раздела добавляются 
возможности чтения из потока. 

    Листинг 15.9.  POINTIN.CPP (классы и потоки ввода) 

    1:	#include <iostream.h> 
    2: 
    3:	class TPoint { 
    4:	private:	
    5:	   int x, y; 
    6:	public: 
    7:	  TPoint() { x = у = 0; } 
    8:	 TPoint(int xx, int yy)	{ х = хх; у = уу; } 
    9:	  void PutX(int xx) { x =	хх; }     
    10:	  void PutY(int yy) { у =	уу; }   
    11:	  int GetX(void) { return	XI }             
    12:	  int GetY(void) { return	у; }              
    13:	  friend ostreamS operator«(ostream& os, TPoint &p); 
    14:	  friend istream& operator»(istream& is, TPoint &p); 
    15:	}; 
    16: 
    17:	main() 


    388     Часть III. Программирование на ANSI C++ 
