Есть ещё пара деталей, о которых следует упомянуть. Во-первых, возвращаемый оператором присвоения тип — Name &. Выражения, включающие оператор присвоения, имеют тип и значение, которые совпадают с типом и значением левого аргумента после присвоения. В следующем примере значение operator=( ) равно 2.0 , а его тип — double .
double d1 , d2 ;
void fn( double )
d1 = 2.0 ; /* Значение этого выражения равно 2.0 */
Это позволяет программисту написать следующее:
d2 = d1 = 2.0 ;
fn( d2 = 3.0 ) ; /* Выполняет присвоение и передаёт полученное значение функции fn( ) */
Значение присвоения d1 = 2.0 , равное 2.0, и его тип double передаются для присвоения d2 . Во втором примере значение присвоения d2 = 3.0 передаётся функции fn( ) .
Во-вторых, оператор присвоения является функцией-членом. Её левый аргумент — текущий объект ( this ). В отличие от других операторов, оператор присвоения не может быть перегружен при помощи функции — не члена класса.
_________________
275 стр. Глава 23. Оператор присвоения
►Защита от копирования...276
Оснащение вашего класса оператором присвоения может значительно повысить его гибкость. Однако, если это требует слишком большого объёма работы или вы не хотите, чтобы С++ создавал копии вашего объекта, перегрузка оператора присвоения защищённой функцией оградит вас от нежелательного мелкого почленного копирования.
class Name
{
/* ...всё, как и раньше... */
protected :
/* Конструктор копирования */
Name( Name & ){ } ;
/* Оператор присвоения */
Name & operator=( Name & s ) { return *this ; }
}
Присвоения наподобие приведённого далее ( при таком определении ) будут запрещены [ 18 ] .
void fn( Name & n )
{
Name newN ;
newN = n ; /* Ошибка компиляции — функция не */
/* имеет права доступа к operator=( ) */
}
Такая защита от копирования спасает вас от перегрузки оператора присвоения, но при этом снижает гибкость вашего класса.

«Если ваш класс использует какие-либо ресурсы, например, память из кучи, вы обязаны либо разработать удовлетворительные оператор присвоения и конструктор копирования, либо сделать их защищёнными для предотвращения их использования.»
[ Советы ]
______________
18В определении тела защищённых конструктора копирования и оператора присвоения нет необходимости, поскольку они никогда не будут вызываться. Таким образом, вы можете просто указать их в защищённой части объявления класса, никак их не реализуя. — Прим. ред.
_________________
276 стр. Часть 5. Полезные особенности
Глава 24. ИСПОЛЬЗОВАНИЕ ПОТОКОВ ВВОДА-ВЫВОДА...277
ОГЛАВЛЕНИЕ
В этой главе...
►Как работают потоки ввода-вывода 277
►Знакомство с подклассами fstream 278
►Прямое чтение из потока 282
►Что такое endl 284
►Подклассы strstream 285
►Работа с манипуляторами 287
Все программы, которые встречались в книге, читали информацию из объекта сin и выводили её в объект cout . Может, это и не интересовало вас, но эта технология ввода-вывода представляет собой подмножество того, что известно под названием потоков ввода-вывода.
В этой главе потоки ввода-вывода описываются более детально. Но должен предупредить вас: это слишком большая тема, чтобы всесторонне осветить её в одной главе; ей посвящены отдельные книги. К счастью для всех нас, написание подавляющего большинства программ не требует глубоких знаний в области потоков ввода-вывода.
►Как работают потоки ввода-вывода...277
Потоки ввода-вывода основаны на перегруженных операторах operator>>( ) и operator<<( ) . Объявления этих операторов находятся в заголовочном файле iostream , который мы включаем во все программы в данной книге. Коды этих функций находятся в стандартной библиотеке, с которой компонуются ваши программы. Вот листинг некоторых прототипов из файла iostream .
/* Операторы для ввода: */
istream & operator>>( istream & source , char* pDest ) ;
istream & operator>>( istream & source , int & dest ) ;
istream & operator>>( istream & source , char & dest ) ;
Читать дальше