Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SHPORS~1.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
201.73 Кб
Скачать

27. Потоки. Віртуальні операції введення та виведення.

Члены ostream не виртуальны. Операции ввода/вывода, кот может добавлять пользователь, не явл членами, поэтому они тоже не могут быть виртуальными. Одна из причин этого – стремление приблизиться к оптимальному быстродействию для простых операций (помещение символа в буфер). В этом случае быстродействие явл критическим и встраивание необходимо. Виртуальные функции используются только для достижения гибкости операций, имеющих дело с переполнением буфера сверху и снизу.

Тем не менее, иногда программист хочет ввести/вывести объект, для которого известен только базовый класс. Поскольку точный тип неизвестен, правильность ввода/вывода не м/б достигнута просто путем определения оператора >>/<< для каждого нового типа. Вместо этого в абстрактном базовом классе можно ввести виртуальную функцию ввода/вывода. Например: class My_base{ public: virtual ostream&put(ostream&s)const=0; //запись *this в s }; ostream&operator<<(ostream&s,const My_base&r) {return r.put(s);} class Sometype:public My_base{public: …//замещение My_base::put(); ostream&put(ostream&s)const{return s<<*this;}};

Т.е. put() явл виртуальной функцией, кот гарантирует использование правильного <<. Теперь можно написать: ostream&operator<<(ostream&s,const My_base&r){return r.put(s);} void f(const My_base&r, Sometype&s){cout<<r<<s;}.

Т.о. виртуальная функция put() интегрируется в окружение, предоставленное ostream и <<. Этот прием полезен для введения операций, действующих подобно виртуальным функциям, но с выбором во время выполнения, основанным на втором аргументе операции.

Розглянемо приклад віртуальної ф-іі

friend istream& operator>>(istream& i,a*p);{return p->input(i)}//повертає потік

istream& A::input(istream& i) {return i>>a>>b;};

class A {int a; public: virtual istream& input(istream& i)};

class B {int b; public: virtual istream& input(istream& i)};

Тому що неможна зробити віртеальною друєжню ф-ю то ф-іі є дружніми тільки до членів класу

A<-B

28. Форматування потоків. Маніпулятори.

Неформатированный вывод – объект превращается в последовательность символов в соотв с некоторыми правилами по умолчанию. Часто программисту нужно более детализировать управление. Например, необходимо управлять объемом памяти, выделенным под операции вывода, и форматом вывода числа. Управление форматированием ввода/вывода производится классом basic_ios и его базовім классом ios_base. Форматированием управляют набор флагов и целочисленные значения в ios_base потока. Значения флагов определяются при реализации. После установки флаг сохраняет свое состояние, пока не будет сброшен. Однако управление опциями ввода/вывода путем явной установки и сброса флагов грубо и может привести к ошибкам. Для простых случаев более аккуратный интерфейс обеспечивают манипуляторы. Пользоваться флагами лучше лишь с целью изучения приемов реализаии, а не при проэктировании интерфейса.

Ключевая идея манипуляторов заключается в том, чтобы вставлять между объектами (записываемыми или читаемыми) операцию, которая изменила бы состояние потока. Например, мы можем явно требовать, чтобы выходной буфер очистился: cout<<x<<flush<<y<<flush;.

Свтандартная библиотека представляет манипуляторы, относящиеся к различным состояниям формата и изменению состояний. Стандартные манипуляторы определены в пространстве имен std и представлены в <iostream> и <iomanip>. Программист может добавлять и собственные манипуляторы, написанные в том же стиле, что и стандартные.

При формуванні потоков вікористовується базовий класс ios та його похідні класи istream, ostream, a класс iostream походить від них.Для зміми ширіни та іншого форматування змінних використовуються маніпулятори. Вони приймають та повертають ссілку на потік, тому вони можуть об”єднуватися в ланцюг вставок. Н-д cout<<setw(3)<<k<<setw(7)<<b;це еквівалентно cout.width(3); cout<<k; cout.width(7); cout<<b. Встановлювання ширіни данних. Непараметризовані маніпул dec, hex,oct-не приймають ніяких параметрів лише змынюють систему числення до кынця вводу або до зустрічі нового маніпулятора.Також використовуються маніпулятори: left-вирівнювання за лівою границею, rigth. fixed-форматування чисел з плаваючою крапкою. Описання маніпул-в ios.h. fmtflags flags()-cчитує стан потоку.fmtflags flags (.fmtflags)-встаноалює стан потоку. Н-д flags(flags() | ios :: fixed ); ios::setf(fmtflags&)-встанловлює флаги стану потоку. Приклад десяткових що вирівнюються зліва setf (ios::dec | ios::left), Очистка буфера cout<< a<<b<<flugh; щоб так використов. треба перегрузити оператор <<.

ostream& operator<< (ostream&, MT); MT=(*f)(); ios::ostream&flugh(); ostream& (*f)-прототип;

ostream& operator<<(ostream& o, ostream (*f)()) {return o.(*f)();}

В такому вигляді ios::width(int); cout<<a<<width(5)<<c; -виклик ф-іі і тому це невірно. Треба зробити слідуюче.

iostream& operator<<(ostream& o,sm& m){ return m.f(m,i);}

class sm {public: ostream & (*f)(int i); int i; sm(ostream& (*ff)(int i),int ii)

class c

{public: sm& operator()(int ii)}; c width;

c::sm& operator()(int ii) {return sm(ios::width,ii);}

Для роботи з файлами використ такі класи ifstream, ofstream, fstream-керують відкритям та закритям фпйлів. ofstream outf- створює вихідний потік файла, uotf.open(“name”)-потоку outf даэться файл “name”;outf.close()-закритя . По замовчюванню файли відкриваються в текстовому режимі.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]