C++ 3d.Комментарии


Манипуляторы, определяемые пользователем - часть 3


if (*iptr=='-') { // выравнивание влево newFlags|=ios::left; iptr++; } else if (*iptr=='0') { // добавляем '0'ли только если !left fill='0'; iptr++; }

if (*iptr=='*') { // читаем ширину, если есть width=arg1; iptr++;

arg1=arg2; // сдвигаем агрументы влево } else if (std::isdigit(*iptr)) width=getval(iptr);

if (*iptr=='.') { // есть точность if (*++iptr=='*') { prec=arg1; iptr++; } else if (std::isdigit(*iptr)) prec=getval(iptr); else throw std::invalid_argument("c_form"); }

switch (*iptr++) { case 0: return; // конец строки формата case 'e': newFlags|=ios::scientific; break; case 'f': newFlags|=ios::fixed; break; case 'g': break; case 'o': newFlags|=ios::oct; break; case 'x': newFlags|=ios::hex; break; default: throw std::invalid_argument("c_form"); }

if (*iptr) throw std::invalid_argument("c_form"); }

void c_form_private::Formatter::setFormatting(ostream& os) { oldFlags=os.flags(); // очищаем floatfield и устанавливаем свои флаги os.flags((oldFlags & ~ios::floatfield) | newFlags);

if (width) os.width(width); if (fill) fill=os.fill(fill); if (prec) prec=os.precision(prec); }

void c_form_private::Formatter::restoreFormatting(ostream& os) { os.flags(oldFlags);

if (fill) os.fill(fill); if (prec) os.precision(prec); }

Принцип его работы основан на следующей идее: функция c_form<>() возвращает объект класса c_form_private::Helper<>, для которого определена операция вывода в ostream.

Для удобства использования, c_form<>() является функцией, т.к. если бы мы сразу использовали конструктор некоторого класса-шаблона c_form<>, то нам пришлось бы явно задавать его параметры: cout<<c_form<int>(day,"02");

что, мягко говоря, неудобно. Далее. Мы, в принципе, могли бы не использовать нешаблонный класс Formatter, а поместить весь код прямо в Helper<>, но это привело бы к совершенно ненужной повторной генерации общего (не зависящего от параметров шаблона) кода.

Как можно видеть, реализацию манипулятора c_form вряд ли можно назвать тривиальной. Тем не менее, изучить ее стоит хотя бы из тех соображений, что в процессе разработки было использовано (неожиданно) большое количество полезных приемов программирования.




- Начало -  - Назад -  - Вперед -