Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты по ООП.doc
Скачиваний:
4
Добавлен:
14.04.2019
Размер:
596.48 Кб
Скачать

35. Создание собственных операторов вставки и извлечения.

Создание операторов вставки

В С++ имеется лёгкий способ определения оператора вставки для создаваемых классов.

Общая форма функции вставки

ostream &operator<<(ostream &поток, тип_класса объект)

{

// характерный для типа код

return поток;

}

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

В программе-примере перегруженная функция вставки не является членом класса three_d. Действительно, ни функция вставки, ни функция извлечения не могут быть членами класса. При перегрузке оператора вставки левым аргументом является поток, а правым аргументом – объект класса. Поэтому перегруженные операторы вставки не могут быть функциями-членами. Чтобы получить доступ к частным и защищённым членам класса оператор вставки должен быть другом класса. В качестве друга класса, для которого он определён, он имеет доступ к частным данным.

Пример

#include <iostream>

using namespace std;

class three_d {

int x, y, z;

public:

three_d(int a, int b, int c){ x=a; y=b; z=c; }

friend ostream &operator<<(ostream &stream, three_d obj);};

// вывод координат x, y, z (оператор вставки для three_d)

ostream &operator<<(ostream &stream, three_d obj)

{

stream << obj.x << ", ";

stream << obj.y << ", ";

stream << obj.z << "\n";

return stream;

}

int main()

{

three_d a(1,2,3), b(3,4,5), c(5,6,7);

cout << a << b << c;

return 0;

}

Перегрузка операторов извлечения

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

Пример

// получение трёхмерных значений

istream &operator>>(istream &stream, three_d &obj)

{

cout <<

"Enter x y z values, separating each with a space: ";

stream >> obj.x >> obj.y >> obj.z;

return stream;

}

Общая форма экстрактора имеет вид:

istream &operator>>(istream &поток, тип_класса &obj)

{

// код экстрактора

return поток;

}

36. Форматирование ввода-вывода

Форматирование с помощью функций-членов ios

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

Для установки флагов используется функция setf(), чей прототип имеет вид:

long setf(long flags);

Эта функция возвращает предыдущее значение флага, устанавливая его новое значение равным flags. При этом остальные флаги остаются неизменными.

Пример

stream.setf(ios::showpos);

Здесь stream является потоком, на который надо оказать воздействие.

Пример

#include <iostream>

using namespace std;

int main()

{

cout.setf(ios::showpos);

cout.setf(ios::scientific);

cout << 123 << " " << 123.23 << " ";

getchar();

return 0;

}

Данная программа выводит на экран

+123 +1.232300е+002

Для отключения флагов надо использовать функцию unsetf(). Она имеет следующий прототип:

long unsetf(long flags);

Функция возвращает значение предыдущей установки флага и сбрасывает флаги, определяемые параметром flags.

Иногда бывает полезным знать текущую установку флагов. Для этого служит функция flags(). Прототип:

long flags();

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

int width(int len);

char fill(char ch);

int precision(int num);

Использование манипуляторов

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

Табл. 1

Манипулятор

Назначение

Ввод-вывод

dec

Ввод-вывод данных в десятичной форме

ввод и вывод

endl

Вывод символа новой строки с передачей в поток всех данных из буфера

вывод

ends

Вывод нулевого символа

вывод

flush

Передача в поток содержимого буфера

вывод

hex

Ввод-вывод данных в шестнадцатеричной системе

ввод и вывод

oct

Ввод-вывод данных в восьмеричной системе

ввод и вывод

resetiosflags(long f)

Сбрасывает флаги, указанные в f

ввод и вывод

setbase(int base)

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

вывод

setfill(int ch)

Устанавливает символ заполнения равным ch

вывод

setiosflags(long f)

Устанавливает флаги, указанные в f

ввод и вывод

setprecision(int p)

Устанавливает число цифр после запятой

вывод

setw(int w)

Устанавливает ширину поля равной w

вывод

ws

Пропускает начальный символ разделитель

ввод

Пример

#include <iostream>

#include <iomanip>

using namespace std;

int main()

{

cout << setiosflags(ios::fixed);

cout << setprecision(2) << 1000.243 << endl;

cout << setw(20) << "Hello there.";

getchar();

return 0;

}

Программа выдаст на консоль:

1000.24

Hello there.