Г. Шилдт - Полный справочник по C++ (1109478), страница 81
Текст из файла (страница 81)
Глава 20. Основы системы ввода-вывода Вот несколько прямоугольников: >*я>*******>*я ** я> >* > я** я***** > **** >***я ******* > * >я * ь *************я*>********я***я****я*** * Создание собственных функций извлечения Функции извлечения являются антиподами функций вставки. Они имеют следующий вид, тестем ьоретасот»(ьвстеап Ьветеат, класс ЕоЬ/) ( / / Тело фунхлян нзвлечсааа теептг. ветеаи; Функция извлечения возвращает ссылку на поток типа аеетеааь т.е. на поток ввода. Ее первым параметром должна быть ссылка на поток типа аеетеаль Обратите внимание на то, что вторым параметром должна быть ссылка на обьект класса, для которого перегружена функция извлечения. Это позволяет модифицировать объект при выполнении операции ввода (извлечения).
Продолжая совершенствовать класс р)зопе)зоо)е, напишем для него функцию извлечен ия, тветеаи аоретаеот» (аветеаи ьветеат, раппе)>сок ьо) сост « "Введите имя: ветеаи » о.папе; соне « "Введите код города: велена » о.атеасое)е; саьс « "Введите префикс: ветеае » о.ртейтх) сопс к< "Введите номеР: яствами » о.поли соне « "Хп"; тееитг. ветеаеу Хотя зта функция предназначена для ввола, при необходимости ее можно применять для вывода данных и выполнения других операций. Однако лучше руководствоваться здравым смыслом и не использовать ее по прямому назначению, Часть П. Яамк С++ Рассмотрим пример использования функции извлечения для класса рьопеьоо)п. Вапс1ц<)е <Ьовттеаэ> аапс1ос)е <светапд> цвапд патеврасе вой; с1авв риопеЬоо)п ( сЬат паие(ВО]; апе атеасос)е; тпе ртеНх; аг.е пцсп риЬ11с: риопеЬоои() ( )' рйопеЬоо)п(сиат *и, апе а, тпе р, тпс пп) ( ветсру(папе, и); атеасоде = а; ртеаах = р; ) Екает оветеап аоретатот« (овттеапп йветеат, риопеЬооК о)> Йтаепс) австеап йоретатот»(вветеае австеап, рЬопеЬооК ао); ); // Выводит на экран имя и номер телефона.
оветеап йоретаеот« (светаем йветеазп, рЬапеЬоох о) эстевес « о.пате « ветеап « (" « о.атеасос)е « ") "р ветеапп « о.ртеНх « "- « о.пцп « "1п"; тесптп ветеалн // Функция лолжна воэврап~ать ссылку на поток. // Вводит имя и номер телефона. авттеам аоретаеот> (аветеапп аветеат, рЬопеЬоо)п ао) соцс « "Введите имя: эстевес » о.пеппе; соне « "Введите код города: ветеат » о.атеасос)е; соот « "Введите префикс: встеапп » о.ртевах; соне « "Введите номер: встевпп » о.повн соне « "1п"; теецтп встеаи; ) апс паап() рЬопеЬоо)п а; сап » а; соне « а; тееотп О; ) Глава 20. Основы системы вводв-вывода Фактически функция извлечения для класса р)золе)зоо)г не слишком эффективна, поскольку операторы соме необходимы, только если поток ввода связан с интерактивным устройством, например консолью (т.е, когда потоком вини является поток езе).
Например, если функция извлечения применяется к потоку, связанному с файлом, операторы соек становятся непригодными. Забавы ради можете попробовать отменить выполнение операторов сове, если потоком ввода не является поток сйи, Например, можно добавить в программу операторы вида Щ 1Е(всгеаи == сьп) сос» « "Введите имя: Теперь приглашение ко вводу появится только в том случае, если устройством вывода является экран. Создание собственных манипуляторов Систему ввода-вывода можно усовершенспювать, создав свои собственные манипуляторы. Эта возможность является важной по двум причинам. Во-первых, можно сосредоточить несколько операций ввода-вывода в одном манипуляторе. Например, довольно часто в программах выполняется одна и та же последовательность операций ввода-вывода В этом случае их можно объединить.
Это позволяет упростить код и предотвратить случайные ошибки. Во-вторых, собственный манипулятор может понадобиться при работе с нестандартными устройствами ввода-вывсаа. Например, манипулятор можно применять для передачи команд специальному принтеру или системе оптического распознавания. Собственные манипуляторы полностью соответствуют принципам объектноориентированного программирования, но они могут оказаться полезными и лля программ, созданных в рамках процедурного программирования. Как мы впоследствии убедимся, собственные манипуляторы могут помочь более эффективно и просто выполнить любую программу, интенсивно выполня)ощую ввод и вывод данных. Как известно, существуют два типа манипуляторов: для ввода и для вывода.
Кроме топ), манипуляторы разделяются на получающие аргументы и не имеющие их. Честно говоря, процедуры, необходимые для создания параметризованных манипуляторов, сильно зависят от конкретного компилятора и даже от его версии. По этой причине, прежде чем приступать к разработке параметризованного манипулятора, слелует обратиться к документации, описывающей компилятор. В то же время манипуляторы, не имеющие параметров, создаются довольно просю, причем эта процедура для всех компшгяторов одинакова.
Скелет манипулятора, не имеющего параметров, выглядиз. так. опегеап аимя манипулятора (ове еееи ахаеат) ~г кал геев гп л(гнат; Обратите внимание на то, что манипулятор возвращает ссылку на поток типа оеехеехь Это позволяет использовать манипулятор внутри более сложных выражений. Следует иметь в виду, что, хотя формально манипулятор имеет один аргумент, представляющий собой ссылку на поток, при вставке манипулятора в оператор вывода этот аргумент не указывается. Рассмотрим программу, в которой описан манипулятор еееггеи(), устанавливающий флаг е)зояг)>аяе и порождающий вывод чисел в шестнадцатеричном формате.
Мйпс1цбе <1овггеаж> ()йпс1иде <1сгаап1р> Часть й. йа кС++ ияапп пагпе*расе ясдг // Простой манипулятор вывода. оястеат аяеспех(оястеагп аясгеае) ястеан.яетг(1оя::яйонЬаяе)г яетеагп.яесб(1оя::Ьех, 1оя::Ьаяейсе1г)) тегагп ястеапн ) 1пс гпа1п() соне « 256 « " " « яетпех « 256; тегптп Ог ) Эта программа выводит на экран следующие числа. (( 256 Ох100 Очевидна, что манипулятор вееиея используется как часть оператора вывела. Собственные манипуляторы не должны быть слишком слажзгыми. Например, простые манипуляторы 1а() н га() выводят на экран стрелки, направленные влево и вправо.
В1пс1аг)е <аоясгеагп> Вап<1пг)е <1опап1р> авалей пагяеярасе яЫ; // Стрелка, направленная вправо ояггеагп ага(оягтеан аястеав) ( яттеагп « " †-----> геситп ягтеапн ) // Стрелка, направленная влево ояетеагп 61а(оягтеае Ьяттеапг) ( ястеае « " <-- — ---". гегитп ятгеягп; ) 1пг тагпО ( сонг « "Остаток на счету " « та « 1233.23 « "1п"; соне « "задолженность " « та « 567.66 « 1а; Эта программа вьаодит на экран следующие строки. Остаток ня счету -------> 1233.23 Задолженность ----- †> 567,66 <------- Если бы эти стрелки приходилось часто выводить вручную, вы быстро бы устали.
Манипуляторы вывола особенно полезны при передаче кол1анд специальным устройствам. Например, принтер может получать большое количество разнообразных команд, Глава 20. Основы системы ввода-вывода изменяющих размер шрифта или его начертание, а также положение печатвющеи голов щ, Ею~и эти команды выполняются часто, их лучше поручить манипулятору. Все манипуляторы ввода, не имеющие параметров, выглядят следующим образом. "'аггеей ьнлы .кднияуяяиюро(овсгеат авгеот) ( // Код тееитп вгеам; Манинулягор ввода получает ссылку на поток, для которого он вызывается, а затем возвращает ее вызываюгцему модулю.
В следующей программе манипулятор цееравв() предназначен для генерации сипила и ввода пароля. Етпс1иа(е <аовстеав> Ьапсгиое <светдпд> ивапд павеярасе вее(; // Простой манипулятор ввода. Кветеап адееравв(авегеам авегеае) ( апис « '~в'," // Звуковой аигнвл соие « "Введите пароль: геситп ветеаеи ) зпс паз.п() ( сЬат рм(80(: оо ( суп » оееравв » ркн нпгу.е (всгатр(рм, "пароль")); аоие « "Вход в систему выполнен1п"; тееитп 0; ) Обратите внимание на то, что манипулятор должен возвращать ссылку на объект класса Звегеавч иначе его будет невозможно использовать в цепочках операторов ввода-вывода. Часть (!.
Язык С++ Н есмотря на то что система ввола-вывода языка С++ в целом представляет собой единый механизм, система файлового ввода-вывода имеет свои скобе>шости. Частично это обьясняется тем, что на практике чаше всего используются файлы на жестком диске, возможности которых значительно отличаются от всех других устройств. Однако слелует иметь в виду, что файловый ввод-вывод является лишь частью общей системы ввода-вывода, и большая часть материала, изложенного в главе, относится к потокам, которые могут быть связаны с другими устройствами. 6Й Заголовок <Ыгеат> и классы файлов Для реализации файловопз ввода-вывода в програмл>у следует включит.ь заголовок <свехааж>.