Г. Шилдт - Полный справочник по C++ (1109478), страница 88
Текст из файла (страница 88)
Мьлс1ие)е <ховггеам> изьлд павеврасе вгг); зпг мадо() ( 1пг 1: снах *р = 'Это строка"; 1 = хеьлгегрхее саве<дог> (р); // Приведение указателя // к целому числу. Глава 22. Дннаынчвсхаа идентификация типа и операторы приведения з соие « Зз тееиго 0; Здесь оператор кеааеекраее саве преобразует указатель р в целое число, т.е. один основной тип — в другой.
Такое преобразование является типичным для оператора кехпсекркет. еаза. Часть Я. Язык С++ с1авв соипхег 1пс соипхт риЬ11с: соипсег(1пс и) ( т.Е(п <.= иррегЬоипй) соиис е1ве соипс = иррегЬсипсб ) чо1с) генек(1пс п) ( 11(и <= иррегЬоипс)) соипс =- ттт хпс хии() ( 11(соиле > 1онегЬоипс)) гегихп саине--т е1ве гесигп 1онегЬоипйт ) Здесь переменные иррегьсяхпст и 1омегьоипо, а также класс соипеег находятся в области вилимости, определенной пространством имен ссипеегнвтеврасе. К илентификаторам, объявленным внутри просцжнсгва имен, можно обращаться непосредствентю, не указывая квалификатор.
Например, внутри пространства имен соипеегтаняалраое функция хип( ) может прямо ссылпъся на переменную 1аеегьоипо. )) 11(соипс > 1омегЬоипс)) гегигп соипг —; Однако, поскольку пространство имен опрелеляет область видимости, для ссылок на обьекты, находящиеся вне этого пространства, необходимо применяп оператор разрешения области видимости. Например, чтобы присвоить число )О переменной иррегьеипа в модуле, находящемся вне п)югтрансгаз имен соипеегмаееврасе. следует выполнить оператор, принеденный ниже. $ Соииеегиавеярасет:иррегЬоиис) = 10т Чтобы объявить объект класса соипеег вне пространства имен соииеегивлтеврасе, необходимо применить следующий оператор. )у Соипгегиалтеврасе::соипгег оЬт Как правило, чтобы обратиться к элементу пространства имен извне, следует перед его именем указать имя пространства и оператор разрешения области видимости. Рассмотрим программу, демонстрирующую применение пространства имен соилеегиваеврасе.
// демонстрация пространства имен. Е1пс1ис)е <1овггеалт> ив1ио палтеврасе вес); патпеврасе Соипеегиапеярасе 1ис иррегЬоипс)т ъпс 1омегЬоипс)т с1авв соипеег [ 1пе соипхт Глава 23. Пространства имен, преобразования функций н другие новшества риЬ11с: соиптет(йпт и) ( 11(п <= ирретЬоипо) сопит = пр е1ве сопит = ирретЬоип((; иоЫ гееес(йпс и) 11(п <= ирретЬоипо) соипс = и; тпт тип() ( 11(сопит > 1оиетЬоипо) тетитп сопит--( е1ве тетигп 1оиетЬоипс]; ] 1пт ва1п() ( Соиптетнавеярасе::ирретЬоипс] = 100; Ссиптегнавеарасе::1оиегЬоипо = О( СоипсехнавеЯрасе::соипсет оЬ1(10); 1пт Оо ( = оЬ1.тип(] г сост « 1 « ) иб11е(1 > Соипсетнавеврасе::1оиегЬоипс]]; саиТ « епо1; Соиптетнавеарасе::соиптег оЬ2(20) оо ( 1 = оЬ2.тип(); сост « 1 « ] иб11е(1 > Соиптегнавеврасе::1оиетЬоипс1); соис « еп01( оЬ2.гевет(100); Соиптегнавеярасе::1оеегЬоип<] - "90; с(о ( = оЬ2.
тип(]," сост « 1 « ] иб11е(1 > СоиптетнавеЯрасе::1оеетЬоипс]," тетитп 0; ) Обратите внимание на то, что объявлению обьекта класса соипеег и ссылкам на переменные иррегЬоипа и 1оеегЬоший предшествует квалификатор Соипсегиавеярасе. Однако после объявления объекта класса соипеег сто члены можно использовать без квалификатора. Таким образом, функцию оьй.тип(] можно вызывать непосредственно, поскольку соответствуюшее пространство имен подразумевается. юв Чает И. )(змкС++ Директива ияпя Лсгко прсдсшвить, во что превратится программа, в которой часто встречаются ссылки на элсмегпы пространства имен. К сожалению, ее текст станет малопонятным, поскольку будет пестреть квалификаторами и операторами области разрешения видимости.
Чтобы избежать этого, слслует применять директиву ив1пд, имеюшую такой вид. ив1пя памеврасе лате; 1 ив1по лате::яетьег; В первом варианте параметр лате задает название пространства имен. Все элементы этого пространства сзановягся частью текущей области видимости и могут использоваться без указания каалификатора. Вп втором варианте в область видимости включается только конкретный элемент пространства имен. Предположим, что в программе обьяалено пространство имен соипеехтгагпевтяхсе. Тогда можно применить следуюшие операторы. ив)пд Соипеегнагяеарасе::1омегЬоипс)г // Пидньяям является // только член 1омегЬоипс). 1омегЬоипг) = 10." // Правильный оператор, поскольку переменная // 1оъегЬоипп является видимой.
ив1пп паиеврасе Соипхегиатепрасег // Все члены видимы. иррегЬоипс) = 100г // Правмльньгй оператор, поскольку все члены // является видимыми. Следуюшая программа представляет собой переработанный вариант прсдьшушсй пргираммы, иллюстрируюший применение оператора ив1пв. // Демонстраиня директивы ив1пп. а1пс1иг)е <1овегеам> ивхпп павеврасе вЫг пагаеврасе Соипсегиаееярасе 1пс х~ррегЬоипг)г 1пс 1омегЬоипс)г с1авв соипсег ( 1пе соипег риЬ11с: соипхег(1пх и) 11(п <= иррегЬоипг)) спиде = пг е1ве соипс = иррегЬоипс)> ) чо1г) гевес(1пг и) ( 11(п <= иррегЬоипг)) соиле = п) ) 1пе гип() 11(соиле > 1омегЬоипс)) гегигп соиле--г е1ве гехигп 1омегЬошЫг ) 1пс гаа1п ( ) глава 2З. Пространства имен, преобрвм)ванна Фуикпий и другие навшествв // Используется только член иррехЬоипг) // нз пространства имен Соипеехпаглеврасе.
ивтпд Соипеехиаееярасе:."иррехЬоипен // Теперь квалифнкатор перед переменной иррехЬоипе) не нужен. иррехЬоипе) = 100; // Перед переменной 1омегЬоипс) квалнфнкатор нужен. Соипевхиапеврасе:.1омехЬоипг) = 0; Соипхегнат»еярасе::соипхег оЬ1(10); 1пс 1; с)о = оЬ1. хин(); соис « 1 « ми(1е(1 > Соипсехназьеярасе::1омехЬоипг)) соис « епг)1; // Теперь доступно все пространство имен Соипхегиаееврасе. ивтпв памеврасе Соипхехнапеврасе; соипеех оЬ2(20)г г)о ( 1 = оЬ2.хип() г соис«з « ) ми11е(1 > 1омехЬоипг)) соих «епс)1; оЬ2.хевех(100); 1оъехЬаипг) = 90( с)о = оЬ2.хоп[)г саих « 1 « ) ьй11е[1 > 1омехЬоипе)) гееигп 0; Зта программа иллюстрирует еше одно полезное свойство: одно пространство имен не перекрывает другого.
Открывая пространство имен, вы просто лобавляете его члены к элементам текушей области видимости. Таким образом, в конде программы, кроме глобального пространства имен, доступными оказываются также пространства имен вс»т и соипсегмазвеврасе.
Неименованные пространства имен Сушествует особая разновидность пространств имен — неименованное л//аетранппво мчео (иппатес) нагло»расе), позволяюшее создавать уникальные идентификаторы, область видимости которых ограничена Файлом. Неименованные пространства имен иногда называют безыч»г»л»ни (апопугпооз папюзрасез). Их объявление имеет следуюший вил. пазьеврасе ( // Объ»гиена» ) ь(деть И. ((аык С++ Неименованные пространства имен позволяют создавать уникальные идентификаторы, область видимости которых ограничена файлом.
Иначе говоря, внутри файла, содержащего неименованное пространство имен, элементы э.пло пространства можно использовать без квалификаторов. Впе файла эти переменные считаются невидимыми. Неименованные пространства имен позволяют избежать применения специфика- тора веве1е. Как указывалось в главе 2, спецификатор веаейе позвапяет сузип область видимости глобального имени до размера файла.
Рассмотрим два файла, являющихся частью олной и той же программы. ехеегп ьпе Кг тото (2(! ( Х = 10/ // Ониска'. ) веаего ьпе )гг чоъд 11() Х = 99г // Все правильио) второй фам ехеегп ьпе Хг ооьв Й2() ( Х = таг // О* Ока) паееерасе ( ьпе )гг ) ,а 11() ( 99; ) // Все правильно> В этом примере область видимости переменной )е по-прежнему ограничена первым файлом. Создавая новые программы, вместо спецификатора веас1е следует приме- нять неименованные пространства имен. Некоторые особенности пространств имен Одно и то же пространство имен можно объявлять несколько раз.
Зто позволяет распределить олно пространство имен среди нескольких файлов и даже разделить его внутри одного файла. $1пс1иое с1оесгеагв> иезид пап1еерасе вес)) пагвеарасе НВ ( 1пе 1/ ) Глава 23. Пространства имен, вреобрвж)евнин функций и другие новшества Поскольку переменная )с определена в первом файле, в нем она используется без каких- либо ограничений. Во жором файле переменная )е определена с помощью ключевого слова еиеегп. Зто означает, что в данном файле имя и тип переменной )г считаются известными, хотя сама она в нем не опрелелена.
Если эти два файла сглзаны между собой, попьпка использовать переменную )е во втором файле вызовет ошибку, поскольку персменная )е объявлена статической, и ее область видимости ограничена первым файлом. Несмотря на то что язык С++ по-прежнему допускает применение ситических глобальных переменных, того же эффекта можно добиться с помощью неименованного пространства имен. Рассмотрим пример. пашеврасе ИЯ ( 1пс ) гпс шазп<) < ИЯ::з = ИЯ::й = 10; // Конкретная ссылка на простран~тво имен ИЯ.
собес « ИЯ::1 ° ИЯ::5 « ' 1п"г // Применение пространства ИЯ. ивьпд пашеврасе ИЯ; соне « 1 * ге<пгп 0; Результаты работы втой программы приведены ниже. ~ 100 В дашюм примере пространство имен ив разделено на две части. Однако содержимое каждой части по-прежнему находится в одном и том же пространстве имен ия. Пространство имен лолжно быль объявлено вне какой бы то ни было области видимости. Это значит, что пространство имен нельзя объявлять, например, внутри функнии, Однако сушествует одно исключение: пространства имен могут быть вложенными. Рассмотрим следуюшую программу. $(пс1иде <1овсгеаш> ив1пя пашеврасе вгбг пашеярасе ИЯ1 ( ьпг пашеврасе ИЯ2 ( // Вложенное пространство имен 1пс й/ ) 1пс ша1п<] ( ИЯ1::1 = 19< // ИЯ2::б = 10; Ошибка, пространство имен ИЯ2 // находится вне области видимости. ИЯ1::ИЯ2:.з = 10< // Это правильно! сонг « ИЯ1::1 « " "« ИЯ1::ИЯ2::б « "Ы"г // использование пространства имен ИЯ1 пв1по пашеврасе ИЯ1; /* Теперь, поскольку пространство имен ИЯ1 находится в области видимости, для ссылки на переменную З монне использовать пространство имен ИЯ2.
*/ сонг « 1 * ИБ2.":3г час ь й. й< С++ кеснкп ог ) Результаты этой программы приведены ниже. 19 10 190 В данном случае пространство имен ива вложено в пространство имен ив1. Следовательно, в начале программы при ссылке на переменную 5 нужно указывать названия обоих пространств имен, которым она принадлежит. Одного имени ива недостаточно. После выполнения директивы $ ивьпц пеееврасе НБ1: можно указывать только имя ива, поскольку пространство имен ио1 уже находится в области видимости. Обычно в небольших программах нет необходимости создавать пространства имен.
Однако библиотеки, которые должны быль как можно более независимыми, следует помешать внутрь собственного пространства имен. ~3 Пространство имен вИ Стандартная библиотека языка С++ пребывает в собственном пространстве имен вес. По этой причине большинство программ, приведенных в книге, солсржат директиву В ивьпд пезпенрасе вес); Этот оператор открывает прямой доступ к функниям и классам, определенным внутри библиотеки, поэтому квалификатор вео:: не нужен. Разумеется, при желании можно явно указывать квалификатор вео: г.
Например, в следуюшей программе стандартная библиотека не включается в глобальное пространство имен. // Применение явного квалификатора вес): а1пс1иг)е <1овккеаа> 1пс шаьп() ьпс ча1г асй::ссис « "Введите номер: вМ::сзп » ча1г яег)::сспс « "Втс нас и ер: вМ::соус «эМ::)зек «ча1; кесскп 0; Здесь потоки сесе, с1п и манипулятор )зех сопровождаются указанием квалификатора ведг:. Иначе пзворя, при записи в стандартный поток вывода нужно задавать имя вео:: ссре, при чтении из стандартного потока ввода следует задавать имя асдг:сап, а манипулятор формата необхолимо вызывать по имени вес::Ьех. Если программа не очень широко использует средства стандартной библиотеки, се можно не включать в глобальное пространство имен. Однако, если программа содер- Глава 23.