Б. Страуструп - Язык программирования С++. Специальное издание, 3-изд. Бином. 2004 (1160791), страница 50
Текст из файла (страница 50)
Методы объединения, изложенные здесь и в слсдуклцих разделах, совместно с механизмом йгпс!ас!е Я 9.2.1), обеспечивают необходимую поддержку для реализации этих требований. 8.2.8.1. Отбор Иногда нам требуется доступ только к нескольким именам из пространства. Мы можем реализовать это, написав определение пространства имен, содержащее только требуемые имена. Например, мы могли бы написать объявление версии Н!е 81ппу, содержащее только Яппи нз Нге е1ппд и оператор конкатенации; патеерасе Н!е егг!яу ( //только «аопьНге в!пну с!аев Ягг!ау(/*,.
*/В 31г!ну ар его 1 ос«(соле! 5 ге!ауй, со ае1 Яг!ауй(; 5!ггпу орегагог«(соне! спадй, соле! сЬаг*) Но если я не являюсь разработчиком или сопровождающим Н!е е1ппу, такой подход легко молгет привести к путанице. Изменения в «настогггцем пространстве Нге е1ппу не будут отражены в данном объявлении. Отбор средств из пространства имен более явно производится прги помощи из|ау-обьявленггя: 225 8.2. Пространства имен патезрасе Му к!Пну ч ик!пуН!я я1г!пу 51г!пу, из!пдН1к я1ппу.орега1ог';, // и,веется в виду забой ч- из Нм я1г(пд ия!лд-объявление помещает любое объявление с указанным именем в область видимости.
В частности, единственное из!ну-объявление делает видимыми все версии перегруженной функции. В нашем случае если разработчик Н!з з1г11чу добавит к 51г!ну функцию-член нли введет перегруячеппую версию оператора конкатенации, зти изменения автоматически станут доступными пользователям Му я1г!пу. С другой стороны, если средство удалено из Н!я з1Ппу пли изменился интерфейс, использование Му з1г(пд, ставшее некорректным, будет обнаружено компилятором (см. также 8 15.2.2). 8.2.8.2.
Объединение и отбор Комбинация объединения (при помощи иялд'-директив) и отбора (при помочци ия!пу- обьявлений) обеспечивает гибкость, требуемую для большинства реальных задач. Ис- пользуя зги механизмы, мы можем обеспечить доступ ко множеству средств таким образом, чтобы разрешать конфликты имен и неоднозначности, возникающие из-за объединснця. Например: патезрасе Н!к !чЬ ( с!аяз 51г!пу( /* .. /)' 1етр!а1е<с!аяя Т с!аяк чгес1ог(/",, */); //- патезрасе Нег НЬ ( 1етр!а1е<с!азз Т> г!аяк Ъес1ог(/' ...
'/); с!аяз 51г!пу( /" ... '/), //- ) патеярасеМу !чЬ( ик1пу патекрасе Н!з !чЬ, ик(пу патекрасе Нег !!Ь; //все изНЫ ЙЬ //все из Нег УЬ // разрешение возлчожних //конфликтов в пользу Нгз !1Ь // разрешение возможных // конфл«кчпов в пользу Нег ЬЬ ик(пуН1к !1Ь ч81г(пу; ик!ну Нег !!Ь:ч!есгог, 1етр!а!с<с!пзз Т> с!вяз Тля! (/* ... '/); //и т д.
//" Имена, явно объявленные в пространстве имен (включая имена, объявленные с помощью из!пу-обьявлений), имеют приоритет по отношению к именам, сделанным доступными при помощи из!пу-директив (см, также Ь' В.10,1). Следовательно, пользователь Му НЬ увидит, по конфликты имен Яг(пд и 1гес1ог будут решены в пользу Н!я !!Ьс51г!пу и Нег !!ЬсЬес1ог. Кроме того, Му НЬсЕ!к1 будет использоваться по умолчанию, независимо от того, имеется лчч Е!з1 в Н!з ПЬ или Нег НЬ.
Глава 8, Пространства имен и исключения 228 Как правило, я предпочитаю не менять имя при включении его в новое пространство имен. В этом случае мне не надо помнить два различных имени для одного объекта. Однако иногда требуется новое имя (или просто так удобнее). Например: патекрасе А162 ( //всеизНН РЬ 0всеизНег 66 изгпд патекрасе Нйз 1!Ь; ик1пу пагпекрасе Нег 116; икгпуН1к 116.5!под; ик1пдНег 1ГЬ Ъес1ог; // «ерен,ее но ванне 0 «переименованиез гурег(езНег ЕЬь51гтуНег згнпя, 1етр1а1е -с!акз Т> с!иккНгк оес .ри611сН1з 116лЪесгог«Ть(/'..."/); 1етр1а1е«с1акк Т с(акко!к1(/*.,'/); //ига д.
//. В языке нет специальных средств для переименования, Вместо этого используется обычный механизм определения нового объекта. Миллионы строк кода на С и Се ь используют глобальные имена и существующие библиотеки. Как мы можем воспользоваться пространствами имен для уменыпения проблем в таком коде? Не всегда возможно переписать код. К счастью, библиотекамп С можно пользоваться так, как будто онн были определены в пространстве имен.
Однако, этого нельзя сделать с бпблиотскамп, написанными на С - Я 9.2.4). С другой стороны, пространства имен реализованы таким образом, что их легко добавить с минилзапьными затратамп в старые программы на С- -. 8.2.9.1. Пространства имен и С Рассмотрим первую каноническую программу на С: и!ос!и«ге <згсуо Ь> ьп1 та!и (( ( ргту' (" Здравствуй, мирР,п "(; Далеко не лучшей идеей было бы изменение программы, так же как и создание специальных версий стандартных библиотек. Поэтому правила языка для пространств имен разработаны таким образом, чтобы можно было программу, написанную без использования пространств имен, сравнительно легко переделать в более явно структурированную версию с применением пространств имен.
В действительности, пример программы калькулятора (Э б.1) является воплогцением такого подхода. 8.2.9. Пространства имен и старый код // разрешение воэмол них О конфликтов в пользу!!и ЬЬ //разрешение возмозкных // конфлоктов в пользуНег !и 227 8.2. Пространства имен Ключом к решению является ия)лд-директиоа. Например, объявления стандартных средств ввода/вывода С в заголовочном файле яЫго.л помещены в пространство имен следующим образом: // яГа)о.)к латеярасе яЫ ( тг рг)пг/)сапог сйаг*...
); // ия)лд патеярасе яЫ; Это обеспечивает совместимость сверху вниз. Для тех, кто пе желает присутствия неявно доступных имен, определен новый заголовочный файл сяййо: // щтгоо: патеярасе яЫ ( )ля рпп~/)соля1 сйаг'... ); //- Создатели стандартной библиотеки Се +, которые хотят избежать повторных объявлений, конечно жс, определят Майо./г путем включения сяййо: // я~йоук Л)псЬЙе<сяяа1о> аятд ягг/::ргт)/, Я рассматриваю глобальные иятр-д'ирективы в основном как средство переноса старого кода. Большая часть кода со ссылками на имена из других пространств имен может быть выражена более ясно при помощи явных квалпфикаторов и ияглд-обьявлений. Связь между пространствами имен и компоновкой описана в 5 9.2А. 8.2.9.2. Пространства имен и перегрузка Механизм перегрузки 8 7А) работает сквозь границы пространств имен.
Это является важным моментом для осугцсствления перехода от существующих библиотек к использованию пространств гглген с минимальными изменениями в исходном коде. Например: // старый Л.Л: ооЫ/))лг); 0 // старый Вин ооЫ/)сйаг), //-. // оп~орый ляяг г; л)лс!идее А.Ь" л! лс1ийе "В.Ь" ооЫд)) Глава 8. Пространства имен и исключения 228 ( Х('а'); //вызывается/1) из В В ) Эта программа может быть модифицирована с использованием пространств имен без изменения содержательной части кода: //пввыйА.1и патезрасеА ( ивпЦ(1л1) //... // повии В.)и латеэрасе В ( ив1й/(сйаг); //.„ // новый иэегс: №1пс1ийе'А Ь №1лс!ийе В.Ь' иэ(лд патезрасеА; из)ля латезрасеВ; ив(йд () Х('а'); //вызывается/() из В.Ь ) Если бы мы хотели оставить изет.с совершенно без изменений, мы могли бы помес- тить ив/лп-директивы в заголовочные файлы.
патезрасе А ( (лЩ; ) // тепер»Д) явллется членом А латезрасеА ( (лги (); // теперь иЯ), и 81) являются плеваки Л Мы можем таким образом поддерживать болыпнс фрагменты программ при помощи единственного пространства имен, подобно тому, как старые библиотеки и приложения «жили в одном глобальном пространстве. Для реализации этого мы должны «распределить» определение пространства имен по нескольким заголовочным файлам и нескольким файлам исходного кода. Как показано на примере калькулятора Я 8,2А), открытость пространств имен позволяет нам реализовывать различные интерфейсы для различных категорий пользователей, открывая для них толь- 8.2.9.3. Пространства имен открыты Пространства имен о~крыты; это означает, что вы можете добавлять к нпм новые имена в нескольких объявлениях.
Например: 229 8 2 Пространства имен ко необходимые фрагменты пространства имен. Открытость также полезна для перехода от старо~о кода. Например, фрагмент //мой заголовочный фтон оогдЩ, //моч функция //." и!п с!и с!е згс)!о )с> )агам)), 0 можно переписать, не меняя порядок объявлений: //лссссс заголовочный файлс пот евра се Мте ) ио)сЩ, // лоя функция //" ) и!пс!ис)еле!с)го Ь> патезрасеМспе) сагу О, //ссоя функс)ия //... ' ) Компилятор обнаружит зту ошибку.
Однако, ввиду того, что новые функции могут быть объявлены в пространстве имен, компилятор не сможет обнаружить аналогич- ную ошибку при повторном открытслп пространства: О повторное открытие Мте с целью определена ч функций // проблелса: в Мте нет объявлениями), // зптлс определением в Мспе добавляеспсяу'!) п атезрасе Мс не ( пои!./П 1 //-. //- Компилятор не может знать, что вы не хотели завести новую функциюЯ )). Псевдонимы пространства имен могут использоваться для уточнения имени при определении.
Тем не менее, онн не могут применяться для повторного открытия пространства имен. При написании нового кода я предпочитаю использовать несколько относительно небольших пространств имен Я 8.2.8), а не помещать большие фрагменты кода в единственное пространство имен. Однако, при модификации больших фрагментов с целью использования пространств имен зто часто не слишком удобно. При определении предварительно объявленного члена пространства имен безопасней пользоваться синтаксисом Я!пел по сравнению с повторным открьстиеьс пространства Мспе.