Бьерн Страуструп - Язык программирования С++. Главы 8-10 - Ввод пользовательских типов

ОГЛАВЛЕНИЕ


10.3.3 Ввод пользовательских типов

Операцию ввода для пользовательского типа можно определить в точности так же, как и операцию вывода, но для операции ввода существенно, чтобы второй параметр имел тип ссылки, например:
     istream& operator>>(istream& s, complex& a)
     /*
 формат input рассчитан на complex; "f" обозначает float:
            f
            ( f )
            ( f , f )
     */
     {
        double re = 0, im = 0;
        char   c = 0;

        s >> c;
        if (c == '(') {
            s >> re >> c;
            if (c == ',') s >> im >> c;
            if (c != ')') s.clear(ios::badbit); // установим состояние
        }
        else {
            s.putback(c);
            s >> re;
        }

        if (s) a = complex(re,im);
        return s;
     }
Несмотря на сжатость кода, обрабатывающего ошибки, на самом деле учитывается большая часть ошибок. Инициализация локальной переменной с нужна для того, чтобы в нее не попало случайное значение, например '(', в случае неудачной операции. Последняя проверка состояния потока гарантирует, что параметр a получит значение только при успешном вводе.

Операция, устанавливающая состояние потока, названа clear() здесь clear - ясный, правильный), поскольку чаще всего она используется для восстановления состояния потока как good(); значением по умолчанию для параметра ios::clear() является ios::goodbit.