Г. Шилдт - Полный справочник по C++ (1109478), страница 80
Текст из файла (страница 80)
В1пс1и<(е <1овегеапп> В1пс1и<)е <асгпап1р> ивапд патпеврасе всп); 1пс гпаап() ( саик «веейовг1адв (1оа:: впсыров); Часть П. Язык С++ посс « вес1оз(1ацз(1оз::зцонЬазе) посс « 123 « " " « цех « 123; геспгп О; ) Манипулятор вее1ов21адв() и функция веет () ВЫПОЛНЯЮТ олинакОВыс оПЕРации. Манипулятор Ьоо1азриа более интересен.
Он позволяет вводи~ь и выводи~ь логические значения, используя ключевыс слова сгпе и еа1ве, а не числа. агпс1цзе <1озсгеап> цз1пд пазезрасе зсг); гпс за(пО Ьоо1 Ьг Ь = сгпе," попс «Ь « ' " «Ьоо1а1рца «Ь «епг)1; соне « "Введите булаве значение; сгп » Ьоо1а1риа » Ь; попс « "Вы ввели следупзее значение: « Ь; геспгп Ог Рассмотрим примерный сценарий се работы. 1 сгпе Введите Оулево значение. "Еа1зе Вы ввели следующее значение: ба1зе 4 Перегрузка операторов "<<" и ">>" Как известно, операторы '«" и "»" в языке С++ перегружены и позволяют вводить и выводить данные встроенных типов.
Кроме того, операторы '"«" и "»" можно перегрузить так, чтобы они вывалили объекты классов, определенных пользователем. Оператор вывода "«" называется олераглором всн~авки (ныепюп прага(ог)„потому что он вставляет символы в поток. Аналогично оператор ввода "»" называется олераглором извлечения (ех(гас(юп орсгасог), потому что он извлекает символы из потока.
груикции, перегружаюц(ис операторы вставки н извлечения, называются функциями вставки ()пзенегз) и извлечения (ехпаглогз) соответственно. Создание собственных функций вставки Создание собственных функций вставки не вызывае~ особых трудностей. Все они имеют следуюц(ий вид. а г озсгеат ьорегасог«(озсгеаз лисео~и, к1асс сЬ)) ( // Гало функции выпивки ) Обратите внимание на то, гго функция возврац(ает ссылку на поток типа овсгеюа (Напомним, что класс евсеевы является производным от класса 1ов.) Кроме того, первый Глава 20. Основы системы ввода-выведа параметр функции является ссылкой на поток вывода. Второй параметр прслставляст собой объект, по»лежащий вставке.
(Второй параметр может быть также ссылкой на этот объект.) Прежде чем закончить свою работу, функция вставки должна»срнуть указа/лель на лоток, Эю позволяет использов»ть функции вставки внутри сложных выражений. Внутри функции вставки можно выполнять любыс операции. Собственно, именно они определяют сущность функции. Однако функцию вставки нс следует слишком усложнять. Например, совсршснно нецелесообразно заставлять функцию вставки попутно вычислять число "пи" с точностью до 30 десятичных цифр! Продемонстрируем функцию вставки на примере объектов класса ръопеьооъс с1авв рпопеЬоох риЬ1хс: онат паке[80); хпс атеасас)е; хпс ртесхх; хпс пик; рпопеЬоок(онат *и, хпс а, хпс р, хпс пп) ( вхтсру(папе, и); атеасобе = а; ртеххк = р; пш» = гв»; В этом класса хранятся имена и номсра телефонов.
Посмотрим, как выглядит функция вставки лля этого класса. // Вывести на экран имя и номер телеФона. о»Стает »орет»Сот« (о»Стает авттеаг», риопеЬоок о) ( »стева « о.паке « встеаи « "(" « о.атеасо<)е « ") »стеке « о.ртеххх « "-" « о.пот « "Хп"; теситп встеак; // Функция должна воэвраиать ссылку на поток ) Ниже приведена короткая программ», иллюстрирующая применение функции лля вставки абьсктов класса рьопеьоои в поток вывода Вхпс1пг)е <ховстеак> ахпс1пг)е <свттхпдв пвхпд о»ив»расе всс)," с1авв риопеЬоо)< риЬ1хс~ сиат пате[80); 1пС атеасос)е; 1пС ртеххк; ъпс поп; рбопеЬоок(спас *и, хпС а, хпС р, хпС пт) ( астору(пате, п)г атеасос)е = а," ртеххк = р; пша = пи; ) Часть ((.
Язык С++ // Вывести на экран имв и номер телефона. сзстеат ьоретасотк<(озстеещ австеащ, риопеЬоо)г о) ( зстеащ « о.пеще « ветевщ « "(" « о.атевсог)е « ") встеащ « о.ртегах « " †" « о.оит « "М"; теситп ветеащ; // Функция должна возвращать ссылку иа поток ) 1пс паап() ( риопеЬсок а("Тед", 111, 555, 1234); риопеЬоок Ь("йлиса", 312, 555, 5768]; риопеЬоск с("Том", 212, 555, 9991]; ссис « а « Ь кк с; тегитп О) ] Результаты работы этой программы таковы. | Тед (111) 555-1234 йлиса (312) 555-5768 Том (212) 555-9991 Обратите внимание на то; по функция вставки не является членом класса риопеЬоо)с На первый взгляд, это кажется ст)хгнным, однако причину легко понять. Если операторная функция является членом класса, ее левым операндом (неявно передаваемым с помощью указателя еидв) является вызывающий объект.
Кроме того, этот операнд является облекаем класса, членом которого является сама операторная функция. Изменить эту ситуацию невозможно. Итак, если перегруженная операторная функция является членом класса, сс левый операнд является лотоком, а правый — объектом данного класса. Следовательно, перегруженные функции вставки не мо)уг быть членами класса, лля которого они перегружаются. Переменные паве, атеесоае, ртеаах и пим в предыдущей программе являются открытыми, поэтому функция вставки имеет к ним доступ.
То, что псрегружснныс функции вставки не могут быть членами класса, для которого они определяются, кажется серьезным недостатком. Если функция вставки не принадлежит классу, как она может обращаться к его закрытым членаму В предыдущей программе все члены классы были открытыми. Однако инкапсуляция является одним из основных принципов объектно-ориентированного программирования, следовательно, нельзя требовать, чтобы все члены класса всегда были открытыми. К счастью, эта дилемма имеет решение; необходимо сделать функцию вставки дружественной по отношению к указанному классу.
В этом случае первый аргумент перегруженной функции вставки может оставаться патокам, а сама функция получит доступ к закрытым членам класса, для которого она определена. Рассмотрим пример„иллюстрирующий этот прием. аапс1ис)е каозттевщ> аапс1ис)е ссвет1пд> ивапд пащезрасе в'сс); с1авв риопеЬоои ( // Теперь переменные-члены закрыты онат пище[80); Глава 20. Основы системы ввода-вывода Тпс ахеасодег хпс рхеТ1х; Тпс пцмг риЬ11с: рнопеЬаа)г(спет *и, хпс а, хпс р, хпс шк) ( ватару(пеппе, и) г атеасаде = а; ртег1х = рг пцгз = пюг ) бт1епд аестеагэ аарехахахсс(аеххвап аесхеаеч РЬапеЬаой о) )г // Выводит на экран имя и номер телефона.
аесхеею ьаретасаг<с(аастеагэ ьастеап, рьапеьаок о) ( астеэза « а.гаме с< ехтеагп « "(" « а.атеасаде « ) ехгеам сс о.рхебхх « "-" « а.пцю « "хп'г гесцгп есхеаю; // Функция должна возеражать ссылку на поток хпс лаз.г.() рнопеЬоах а("Тед", 111, 555, 1234); рнапеЬаак Ь( алиса", 312, 555, 5765)) рнапеЬао)с с("Том", 212, 555, 9991); сацс « а « Ь « сг тесцхп 0/ ) Определяя тело функции вставки, старайтссь сделать его как можно более унивсрсальным.
Например, функцию вставки из прсдыдушсго примера можно применять к любому потоку, поскольку она направляет данные в объект аггеем, являющийся потоком, вызывающим функцию вставки. Можно было бы написать операторы В встеаю « а.пепе « или $ сацс « о.пате <с Одцко в этом случае поток вывода оказался бы слишком жестко заданным. Исходная версия программы работает с любым потоком, включая поток, связанный с файлом. Хотя в некоторых ситуациях, например, при выводе на специальное устройство у программиста нет выбора, и он может "зашить" поток в программу, в большинстве случаев это пс так. Чем универсальное функция вставки, она ценнее.
Функция всгпавки дпя класса рьапеьааа рабогпавгп прекрасно, пока не всгпре- :йЭ тигпся номер наподобие 003Д Б эпюм случае ведущие нули игнорируются и не выводятся на экран. Чтобы исправигпь этот недоспюток, необходимо либо преобразовать переменную аим е сгпроку, либо задать е качестве символазапапнителя цифру 0 и применить функцию мааса() для генерирования ведущих нулей. Читатели моаугп свми справиться с аглай задачей.
Часть )). Язык С++ Прежде чем псреити к функпням извлечения, рассмотрим еще олин пример функции вставки. Как извсспзо„функции вставки позволяют вывести любые осмысленные данные. Напргзьзср, такая функция для класса, являющегося частью системы автоматизированного просктировання (САГ] — Сощргз(сг-АзОсг) Пса(бп), выводит инструкции плоттера. Лругая функция вставки может генерировать графические изображения. Функции вставки лля ззГзпг)озгтгприложеззий могут выводить на экран диалоговые окна. Чтобы продсмщютрировать вывод объскзов, которые отличаются от простого текста, приведем следующую про~рамму, которая рисует прямоугольники на экране.
(Поскольку графические библиотеки в языке С++ нс определены, программа использует символы, но их можно легко заменить графическими изображениями, если конкретная система позволяет это сделать.) $1пс1цс)е «1овстеалз> пя1по папеярасе вС<(з с1аяв Ьох ( уз роЬ11сз Ьох(зпе 1, 1пС З] ( х=х; у.-]з )' Етзепг) овстеалз аоретасот« (оястеалз австеам, Ьох о] )з // Выводит прямоугольник. овстеалз аоретасох« (овсхеаж аясхеаж, Ьох о) тЕ01всет ьпс.ь, зз Оох(1=0з 1<о.хз т++) встеалз « "*"з встеавз «« "1п"з Ест(З=1з б«о.у-1) Зе+] ( Оот(1=Оз т<о.хз 1++) 11(1==0 )! 1==о.х-1) вез.еам « е1ве встеалз « встеазл к< "1п" з ) 1от(1=0з з<о.х; 1+ь) всхеап <к встеалз « "1п"з теспхп ястеатз зпс аза1п() Ьох а(14, б), Ь!ЗО, 7), с(40, 5) з сопС <« "Вое несколько прлмоугольззиковзз,п"; сопс « а <« Ь « сз тесптп Оз Программа выводит на экран следующие строки.