Г. Шилдт - Полный справочник по C++ (1109478), страница 89
Текст из файла (страница 89)
Пространства имен, преобразования функций и другие новшества жит сотни обращений к стандартным функциям и классам, будет слишколз утомительно каждый раз указывать квалификатор ведз з. Если в программе используется лишь несколько членов станлартной библиотеки, имеет смысл применить директиву ивдпд к кажлому из них отдельно.
Эти имена по-прежнему можно использовать, не указывая спецификатор всззз з, однако при этом вся стандартная библиотека не погружается в глобальное пространство имен. Рассмотрим пример. // В глобальное пространство имен включается // лишь несколько идентификаторов. ((1пс1иде <1оесгеаш> // Предоставляем доступ к именам соне, сзп и ззех. ивъпд весзззсоисз ивзпд враз зсзпз ивзпд всдззпехз лпе шазп() ( зпс ча1з соне « "Введите номерз сз.п» ча1; соне « кэто ваш номер: соис « Ьех <« ча1з гесигп Оз ) В этой программе имена сдп, еоие и Мех можно использовать непосредственно, а остальная часть библиотеки вед остается вне области видимости, Как известно, первоначально библиотека языка С++ находилась в глобальном пространстве имен.
Если вы работаете со старыми программами на языке С++„в них необходимо включить оператор $ иаъпд пашеврасе всдз или указывать перед каждым членом библиотеки квалификатор ведз з. Это особенно важно, если старые заголовочные файлы заменяются новыми. Помните, что старые заголовочные файлы (.н) помещают свое содержилюе в глобальное пространство имен, а новые — в пространство имен вед. Ы Создание функций преобразования В некоторых ситуациях объект некоего класса должен входить в выражение, содержащее данные других типов.
Иногда этого можно достичь с помощью перегруженных операторных функций. Однако в других случаях необходимо простое преобразование типа в более широкий тип. Для этого язык С++ позволяет создавать собственные з/зулхции преабразааанал (сопчепйоп (ипспопз).
Функция преобразования трансформирует класс в другой тип, совместимый с остальной частью выражения. Общий внд функции преобразования таков. й орегагог зуде() ( гесигп га1иез ) Здесь паралзетр Озре задает результирующий тип, в который преобразуется класс, а параметр га(ие определяет значение объекта после преобразования. Функция пре- Часть й.
Язык С++ образования возвращает объект типа /уре. Никакой другой спецификатор типа не допускается. Кроме того, функция не имеет аргументов. Функция преобразования должна быть членом класса, для которого она определена. Функции преобразования наследуются и могут быть виртуальными. Рассмотрим преобразование класса всае)с, описанного в главе 11. Лопустим, что обьект класса аеас)е необходимо использовать внутри целочисленного выражения. Кроме того„будем считать, что значением объекта класса аеас)г, использованного в целочисленном выражении„является количество элементов, хранящихся в стеке.
(Иногда в процессе моделирования или мониторинга необходимо отслеживать скорость заполнения стека.) Для этого достаточно преобразовать стек в целое число, равное количеству его элементов. Чтобы сделать это, можно применить следующую функцию преобразования. й орегасог ьпс() ( гесигп соз? ) Рассмотрим программу, иллюстрирующую работу функции преобразования. Вьпс1иг?е <толстеет> из?пд пакезрасе зсс?? сопев ?пе ятзд=?ОО? // Создается класс зсас)< с1азз аеас)< ( ?пс вес)г[ятЕЕ): ьпе Соз? ри)з??с: зсас)<(! ( сов=с? чоЫ ризи(ьпс 1); ьпс рор(чей.<?)? орегаеог ьпе() ( гееигп Сов? 1 // Преобразование стека // в целое число.
чоЫ зсас)г::риз??(ьп ( и (еоз==ятял) ( соил < 'Стек полон.хп гзситп? 1 зсск[соз) = 1; сов++; ) ьпс зсасх::Рор() ( ьб(воз==с) ( соис « "Стек пуст.хп"/ гееигп О; соз--; кеситп зсс)<[сиз); ьпс паьп() ( аеас)г зеск? ?пг. з, б? Глава 23. Пространства имен, лреобразоваиив функций и другие новаества тог(1=Ос 1<20," 1++) воск.рпвп(1]; 2 = весим // преобразование в целое число.
соне « б « " элементов в стеке. (п"; сонг « Ятеп - всс]е « " свободных мест.1п"; гЕЕигп 0; Результаты работы этой пропзаммы приведены ниже. ! 20 элементов в стеке. ВО свободных мест. Как видим, когда объект класса аеас]е используется в целочисленном выражении, например 1 вес)е, к нему применяется функция преобразования. В данном случае функция преобразования возвращает число 20. Кроме того, функция преобразования вызывается при вычитании объекта вес]е из константы вхяи. Рассмотрим еще адин пример функции преобразования. Эта про~рамма создает класс рмг, который хранит и вычисляет степень некоторого числа.
Результат записывается в переменную типа бопЪ1е. Применяя функцию преобразования к объекту класса рмг, можно использовать его в выражении типа бомЬ1е. яьпс1ибе <товсгеам> ивтпд памеврасе вен; с1авв рмг ( боиЬ1е Ь; (пе е; бопЫе оа1у риЬ11с: рмг(боиЬ1е Ьаве, 1пе ехр); рмг орегасог+(рмг о) бопЬ1е Ьавеь гпг. ехр; Ьаве = Ь а о.Ь; ехр = е + о.е; рмг еемр(Ьаве, ехр); гегигп секр; ) орегагог бопЬ1е() ( гееигп та1; ) // Преобразование в тип допЬ1е рмг".:рмг(доиЫе Ьаве. 1пе ехр) ( Ь = Ьаве; е=ехр; ча1 = 1," 11(вар==О] геепгпс гог( ; ехр>0; ехр--] та1 = ча1 * Ь; ) тпг мати() ( рмг х(4.0, 2)) бопЫе а; Часть И.
Язык С++ а = х; // Преобразование в тип стоцЫе. соце « х т 100.2; // Преобразуем х в тип г)оцЬ1е // и добавляем число 100.2. соцс « "(и"; рнт у[3.3, 3), г(0, О); г = х + у; // Преобразование не производится. а = гг // Преобразование в тип боцЬ1е. соцс « а; теецтп 0; Результаты работы этой программы приведены ниже.
116.2 20730.7 Как видим, когда объект х используется в выражении и+100.2, ВЫЗЫВаетСЯ фУнкция преобразования, создаюшдя значение типа е(ооые. Обратите внимание на то, что в выражении х+у преобразование типа не вызывается, поскольку оба операнда имеют тип рнт. Из прелыдуших примеров следует, что функция преобразования оказывается полезной во мнопо( ситуациях. Довольно часто функции преобразования позволяют создавать более естественные синтаксические конструкции смешанных выражений, в которые входят как переменные встроенных типов, так и объекты классов, определенных пользователем. В частности, на примере класса рнт видно, что применение функции преобразования в тип аочые позволяет использовать обьекты в обычных математических выражениях В программе можно создать несколько функций преобразования для трансформации объектов в разные типы.
Например, в предыдущий пример можно было бы добавить функцию, преобразовываюшую объект класса рнх в тип 1опя. Каждая функция преобразования автоматически применяется к объекту, входящему в выражение соответствуюшего типа. !:1 функции-члены с атрибутами соп81 и пш1аЫе Функции — члены класса можно объявлять константными. В этом случае указатель сыв считается константным. Следовательно, такая функция не может модифицировать вызываюший ее объект. Однако константную функцию-член могут применять как константные, так и неконстантные объекты. Чтобы определить константную функцию-член, следует использовать следуюшую форму объявления.
с1авв Х ( ьпс вогае чатг рцЬ1(с: Фпг т1 О сопзог // Константная Функция-член Как видим, атрибут сопев указывается после объявления параметров функции. Функцию-член объявляют константной, чтобы запретить ей модифицировать вызывающий объект. Рассмотрим следующий пример. /* демонстрация константной Функции-члена. Глава 22. Пространства имен, преобразование функций и другие новшества Эта программа не компилируется. */ аъпс1иде <1овптеам> ивъпс пазпеврасе вс!)! с1авв пезпо ( з.пс з.! риЬ11с! 1пс десъ() сопят ( тетигп 1! // ОК! ) чоЫ вес((Ыс х) сопят з.
†" хз // Ошибка! ) ) зпс !паап() ( Пепю оЬ! оЬ.ветз.(1900)! соие « оЬ.ПЕСТ()! гееитп О! Эта программа не компилируется, поскольку функция-член веМ() объявлена константной. Это значит, что она не может модифицировать вызывающий объект. При попытке изменить значение переменной 1 возникнет ошибка. й противоположность этому функция яе~. () не пытается молифицировать переменную 1, что вполне допускается Иногда возникает необходимость модифицировать тот или иной член класса с помощью константной Функции-члена, сохраняя в неприкосновенности остальную часть.
Для этого предназначено ключевое слово пмеаЬ1е. Оно отменяет атрибут сззпве. Иначе говоря, член, объявленный с атрибугом пмсаЬ1е, может модифицироваться константной Функцией-членом. Рассмотрим пример. // демонстрация ключевого слова и!исаЬ1е. «1пс1иде <Товегеап!> ивъпд пазпеврасе вс!)! с1авв Пепю и!итаЬ1е зпе з.з з.пе риЬ11с! гпе цееъ<) солне ( тееигп г! // Все верно! чоЫ вета(ъпс х) сопят ( = х! // Теперь все верно! ) /* Эта функция не компилируется. чоЫ весб[ъпс х) сопят ( 5 = х! // По-прежнему неверно! ) */ Часть)!.
ЯзыкС)+ з.пс па1п ( ) Г)еазо оЬз оЬ. весз (1ЭОО) з соие « оь.дее1(]з тесптп Оз Здесь переменная 1 объявлена с атрибутом вазеаЫв, поэтому функция ввсд() может ее модифицировать. Однако переменная з атрибутом звоеаЬ1в не обладает, поэтому функция ввез <) не имеет права изменять ее значение. ~2 Функции-члены с атрибутом чо!абе Функции — члены класса могут иметь атрибут но1ае11в. Следовательно, в этом случае указатель снзв также имеет атрибут но1ае11в. Чтобы определить функцию- член с атрибутом но1ае11в, необходилзо использовать следуюшую форму объявления.
з з з с1ааа Х ( риЫз.сз ното (2(ъпс а) но1ас11ез // Функция-член с атрибутом но1ас11е. )з ~~]з' Явные конструкторы Как указывалось в главе 12, если конструктор имеет только один аргумент, лля инициализации объекта оЬ можно применять выражения оЬ(х2 или оЬ=х. Причина заключается в том, что одновременно с созданием конструктора, имеюшего один аргумент, неявно создается функция преобразования аргумента в объект данного класса. Однако иногда автоматическое преобразование аргумента оказывается нежелательным. Для этой цели в языке С++ предусмотрено ключевое слово вир11етс.
Рассмотрим следуюший пример. Сдпс1пбе <(оэстеазп> пвйпд паазеврасе весй с1ааэ дзус1ааэ ( 1пс аз райс з злус1аэв(1пе х] ( а = хз 1пс дека() ( теспзп аз зпе азатпО ( азус1авв оЬ = 4з // автоматически преобразуется // в вьэзахеяие пзус1авв(4). соне « оЬ.дека()з Глава 23. Пространства инеи, преобразаваиия функций и другие новшества Здесь конструктор вегс1авв имеет олин параметр.