Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

Во-первых, вам необходимо определить временный класс, который делал бы всю работу. Для простоты предположим, что вам требуется написать манипулятор с именем

setWidth
, который делает то же самое, что и
setw
. Временная структура, которую вам необходимо построить, будет выглядеть примерно так.

class WidthSetter {

public:

 WidthSetter(int n) : width_(n) {}

 void operator(ostream& os) const {os.width(width_);}

private:

 int width_;

};

Этот

класс содержит простую функцию. Предусмотрите в ней целочисленный аргумент и, когда
operator
вызывается с аргументом потока, установите ширину для потока в значение, в какое она была установлена при инициализации этого объекта. В результате мы получим
WidthSetter
, сконструированный одной функцией и используемый другой. Ваш манипулятор конструирует эту функцию, и это будет выглядеть следующим образом.

WidthSetter setWidth(int n) {

 return(WidthSetter(n)); // Возвращает инициализированный объект

}

Эта функция всего лишь возвращает объект

WidthSetter
, инициализированный целым значением. Этот манипулятор вы будете использовать в строке операторов
operator<<
следующим образом.

myostream << setWidth(20) << "banana";

Но этого недостаточно, потому что

setWidth
просто возвращает объект
WidthSetter
;
operator<<
не будет знать, что с ним делать. Вам придется перегрузить
operator<<
, чтобы он знал, как управлять объектом
WidthSetter
:

ostream& operator<<(ostream& os, const WidthSetter& ws) {

 ws(os); // Передать поток объекту ws

 return(os); // для выполнения реальной работы

}

Это решает проблему, но не в общем виде. Вам не захочется писать класс типа

WidthSetter
для каждого вашего манипулятора, принимающего аргумент (возможно, вы это и делаете, но были бы не против поступить по-другому), поэтому лучше использовать шаблоны и указатели функций для получения привлекательной, обобщенной инфраструктуры, на базе которой вы можете создавать любое количество манипуляторов. Пример 10.5 содержит класс
ManipInfra
и версию
operator<<
, использующую аргументы шаблона для работы с различными типами символов, которые может содержать поток, и с различными типами аргументов, которые могут быть использованы манипулятором потока.

Пример 10.5. Инфраструктура манипуляторов

#include <iostream>

#include <string>

using namespace std;

// ManipInfra - это небольшой промежуточный класс, который помогает

// создавать специальные манипуляторы с аргументами. Вызывайте его

// конструктор с предоставлением указателя функции
и значения из основной

// функции манипулятора

// Указатель функции должен ссылаться на вспомогательную функцию, которая

// делает реальную работу. См. примеры ниже

template<typename T, typename C>

class ManipInfra {

public:

 ManipInfra(basic_ostream<C>& (*pFun) (basic_ostream<C>&, T), T val) :

manipFun_(pFun), val_(val) {}

 void operator(basic_ostream<C>& os) const {

manipFun_(os, val_);

 } // Вызовите функцию, задавая ее указатель и

private: // передавая ей поток и значение

 T val_;

 basic_ostream<С>& (*manipFun_) (basic_ostream<C>&, T);

};

template<typename T, typename C>

basic_ostream<C>& operator<<(basic_ostream<C>& os,

 const ManipInfra<T, C>& manip) {

 manip(os);

 return(os);

}

// Вспомогательная функция, которая вызывается в итоге в классе ManipInfra

ostream& setTheWidth(ostream& os, int n) {

 os.width(n);

 return(os);

}

// Собственно функция манипулятора. Именно она используется в клиентском

// программном коде

ManipInfra<int, char> setWidth(int n) {

 return(ManipInfra<int, char>(setTheWidth, n));

}

// Ещё одна вспомогательная функция, которая принимает аргумент типа char

ostream& setTheFillChar(ostream& os, char с) {

 os.fill(c);

 return(os);

}

ManipInfra<char, char> setFill(char c) {

 return(ManipInfra<char, char>(setTheFillChar, c));

}

int main {

 cout << setFill('-')

<< setWidth(10) << right << "Proust\n";

}

Если последовательность событий при работе этого класса все же остается неясной, я советую прогнать пример 10.5 через отладчик. Увидев его реальную работу, вы все поймете.

Поделиться:
Популярные книги

Хозяин Теней 3

Петров Максим Николаевич
3. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Хозяин Теней 3

Контракт на материнство

Вильде Арина
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Контракт на материнство

На границе империй. Том 10. Часть 3

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 3

Эволюционер из трущоб

Панарин Антон
1. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Эволюционер из трущоб

Идеальный мир для Лекаря 5

Сапфир Олег
5. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 5

Боец с планеты Земля

Тимофеев Владимир
1. Потерявшийся
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Боец с планеты Земля

Бастард Императора. Том 5

Орлов Андрей Юрьевич
5. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 5

Правильный попаданец

Дашко Дмитрий Николаевич
1. Мент
Фантастика:
альтернативная история
5.75
рейтинг книги
Правильный попаданец

Морской волк. 1-я Трилогия

Савин Владислав
1. Морской волк
Фантастика:
альтернативная история
8.71
рейтинг книги
Морской волк. 1-я Трилогия

Его огонь горит для меня. Том 2

Муратова Ульяна
2. Мир Карастели
Фантастика:
юмористическая фантастика
5.40
рейтинг книги
Его огонь горит для меня. Том 2

Блуждающие огни 4

Панченко Андрей Алексеевич
4. Блуждающие огни
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Блуждающие огни 4

Жена воина, или любовь на выживание

Звездная Елена
3. Право сильнейшего
Фантастика:
фэнтези
8.98
рейтинг книги
Жена воина, или любовь на выживание

Локки 4 Потомок бога

Решетов Евгений Валерьевич
4. Локки
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Локки 4 Потомок бога

Идеальный мир для Лекаря 19

Сапфир Олег
19. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 19