Читаем C++. Сборник рецептов полностью

Поскольку манипуляторы — это просто удобный способ установки флагов формата для потока, следует помнить, что заданные установки работают до тех пор, пока вы их не уберете или пока поток не будет уничтожен. Сохраните флаги формата (см. пример 10.3) до того, как вы начнете его изменять, и восстановите их в конце.

Смотри также

Рецепт 10.3.

10.3. Написание своих собственных манипуляторов потока

Проблема

Требуется иметь манипулятор потока, который делает что-нибудь такое, что не могут делать стандартные манипуляторы. Или вам нужен такой один манипулятор, который устанавливает несколько флагов потока, и вам не приходится вызывать несколько манипуляторов всякий раз, когда необходимо установить конкретный формат вывода.

Решение

Чтобы создать манипулятор, который не имеет аргументов (типа left), напишите функцию, которая принимает в качестве параметра ios_base и устанавливает для него флаги потока. Если вам нужен манипулятор с аргументом, см. приводимое ниже обсуждение. Пример 10.4 показывает возможный вид манипулятора без аргументов.

Пример 10.4. Простой манипулятор потока

#include

#include

#include


using namespace std;


// вывести числа с плавающей точкой в обычном виде

inline ios_base& floatnormal(ios_base& io) {

 io.setf(0, ios_base::floatfield);

 return(io);

}


int main() {

 ios_base::fmtflags flags = // Сохранить старые флаги

  cout.flags();

 double pi = 22.0/7.0;

 cout << pi = " << scientific // Научный режим

  << pi * 1000 << '\n';

 cout << "pi = " << floatnormal << pi << '\n';

 cout.flags(flags);

}

Обсуждение

Существует два вида манипуляторов: с аргументами и без аргументов. Манипуляторы без аргументов пишутся просто. Вам требуется только написать функцию, которая принимает в качестве параметра поток, выполнить с ним какие-то действия (установить флаги или изменить установочные параметры) и возвратить его. Сложнее написать манипулятор, который имеет один или несколько аргументов, потому что потребуется создавать дополнительные классы и функции, которые работают «за кулисами». Поскольку манипуляторы без аргументов более простые, начнем с них.

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

myiostr.setf(0, ios_base::float field);

Но для удобства вы можете добавить свой собственный манипулятор, делающий то же самое. Именно это сделано в примере 10.4. Манипулятор floatnormal устанавливает соответствующий флаг потока для вывода чисел с плавающей точкой в стандартном формате.

Компилятор знает, что делать с вашей новой функцией, потому что в стандартной библиотеке определен следующий оператор для basic_ostream (basic_ostream — имя шаблона класса, инстанцируемого в классах ostream и wostream).

basic_ostream& operator<<

 (basic_ostream& (* pf)basic_ostream&))

Здесь pf — это указатель функции, которая принимает в аргументе ссылку на basic_ostream и возвращает ссылку на basic_ostream. Этот оператор просто обеспечивает вызов вашей функции, которая принимает в качестве аргумента текущий поток.

Манипуляторы с аргументами более сложные. Чтобы понять причину этого, рассмотрим работу манипулятора без аргументов. Пусть используется, например, следующий манипулятор

myostream << myManip << "foo";

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

Для сравнения представим, что у вас имеется манипулятор, который принимает числовой аргумент, так что в идеале вы могли бы его использовать следующим образом.

myostream << myFancyManip(17) << "apple";

Как это будет работать? Если вы считаете, что myFancyManip является функцией, принимающей целочисленный аргумент, то возникает проблема: как передать поток в функцию без включения его в параметры и явного его использования? Вы могли бы написать так.

myostream << myFancyManip(17, myostream) << "apple";

Перейти на страницу:

Похожие книги

1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных
C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных