Программирование >>  Аргументация конструирования 

1 ... 91 92 93 [ 94 ] 95 96 97 ... 108


#include <iostream.h> it include <iomanip.h>

void

cout. < tw ( 8 ) / /ширина поля равна 8... << 10 . . .для 10, но ...

20 для 2 0 равна значению по умолчанию

\п ;

В результате выполнения этого кода сначала будет выведено восьмисимвольное целое число, а за ним Для вывода двух восьмисимвольных значе-

ний нужно сделать так:

#include <iostream.h> #include <iomanip.h> void fn,) {

cout; < tw (8) установить ширину. . . 10 setw(8)

20 ...обновить ее

\n ;

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

Какой же метод лучше - с использованием манипуляторов иди функций? Ф>нкции-члены предоставляют больше контроля над свойствами потока -

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

finclude <iostream.h> voi loat value) {

int previousPrecision;

Вы можете узнать текущую точность так: previousPrecision = cout.precision О;

жно также сохранить старое значение, одновременно изменяя его на новое previousPrecision = cout.precision(2);

cout << value;

Восстановим предыдущее значение

cout.precision(previousPrecision);

Несмотря на все преимущества функционального подхода, манипуляторы

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



Написаниесоаяеенных

C++ обладает потрясающей способностью перегружать оператор сдвига для выполнения вывода. Это значит, что вы тоже можете перегрузить этот оператор, чтобы осуществить вывод собственных классов.

Это наиболее важная особенность потоков ввода-вывода, к описанию которой

я шел на протяжении всей этой главьс, но до настоящего момента старательно избегал упоминания о ней. Итак, представьте себе, что класс USDollar из главы 24, Перегрузка операторов , дополнен функцией display!).

#ifclef WIN32 Iinciude <strstrea.h>

#else

tinclude otrstream. h> If endl f

ttinclude <iomanip.h>

class USDollar

public:

ySDollar(double v = 0.0)

Удалим дробную часть dollars = (int)v;

Преобразуем дробную часть в центы,

добавив 0.5 для округления

cents = int((V - dollars) *- 100.0 + 0.5) ;

operator

return dollars + cents / 100.0;

void out)

out < << dollars .

установим заполнение нулем для центов

setfill{0) 3etw(2) cents

вернем настройку запол.чения пробелами

<<setfill( ) ;

protected:

unsigned int dollars; unsigned int cents;

operator - оператор вставки в поток нашего класса ostreami operator (ostreams о, USDollars d)

d.display(о);

return o;



in (int argcs, char* pArgs [ j )

USDollar usdd .50) ;

cour << Начальная сумма = << usd \n ;

usd = 2.0 usd;

cout Теперь сумка равна usd \n ; return G;

Функции play () начинается с вывода символа $, после чего выводится сумма с обязательной десятичной точкой. Обратите внимание, что вывод выполняется в любой потоковый объект ostream, а не только в cout. Это позволяет использовать функцию drsplayO и ддя объектов fstream и strstream, которые являются подклассами класса ostream.

Когда приходит время отображать количество центов, функция display () устанавливает ширину поля в два символа и заполнение символом 0. Благодаря этому можно быть уверенным, что числа меньше 10 будут отображены правильно. Обратите внимание, что вместо прямого обращения к функции display!} класс USDollar определяет Теперь программист может выводить объекты класса uSDollar с такой же непринужденностью и изяществом, как и объекты встроенных типов, что и демонстрирует функция main ().

В результате выполнения этой программы будут выведены следующие сообщения:

НачалБная сумма = $1.50 Теперв сумма равна S3.00

Вы можете поинтересоваться, зачем функция cperator<<() возвращает объект

класса ostream, передаваемый ей в качестве аргумента. Дело в том, что это позволяет связывать один оператор с другими операторами в одном и том же выражении. Поскольку operator<< () обрабатывается слева направо, выражение

voi о11аг& usd, float i)

cout Сумма usd , проценты = i;

интерпретируется как

void fn.USDollars usd, float i) {

(((cou< Сумма ) << usd) << , проценты = ) << i;

Первый оператор вставки в поток выводит строку Сумма в cout. Результатом

этого выражения является объект cout, который затем передается функции

operator<< (ostreams, USDollarS). Поскольку этот оператор возвращает свой объект как ссылку на ostream, данный объект может быть передан следующему в очереди оператору вставки в поток.

Если бы типом возвращаемого значения оператора вставки в поток вы объявили void, оператор бы оставался работоспособным, но в приведенном примере вызывал бы ощибку компиляции, поскольку вставить строку в void нельзя. Приведенная же в следующем примере ошибка еще опаснее, поскольку ее трудно обнаружить. ostream operator<<(ostreams os, USDollars usd) (

usd.display(os);

return cout;



1 ... 91 92 93 [ 94 ] 95 96 97 ... 108

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика