Г. Шилтд - Самоучитель C++ (DJVU) (1114955), страница 57
Текст из файла (страница 57)
Пространство имен должно объявляться вне всех остальных областей видимости за исключением того, что одно пространство имен может быть вложено в другое. То есть вложенным пространство имен может быть только в другое пространство имен, но не в какую бы то ни было иную область видимости. Это означает, что нельзя объявлять пространства имен, например, внутри функции. Имеется пространство имен особого типа — безымянное пространство имен <'илпатеЫ патезрасе). Безымянное пространство имен позволяет создавать идентификаторы, являющиеся уникальными внутри некоторого файла. Ниже представлена основная форма безымянного пространства имен: Глава 13.
Пространства имен идругие темы 387 пагпеврасе О обалвтгена.е Безымянные пространства имен дают возможность задавать уникальные идентификаторы, известные только внутри области видимости одного файла. Чаким образом, внутри файла, содержащего безымянное пространство имен, к членам этого пространства можно обращаться напрямую, без необходимости каких бы то ни было уточнений. Но вне этого файла такие идентификаторы неизвестны. Вам вряд ли понадобится создавать свои пространства имен для небольших и средних по объему программ. Однако, если вы собираетесь создавать библиотеки функций или классов, предназначенных для многократного использования, или хотите гарантировать своим программам широкую переносимость, вам следует рассмотреть возможность размещения своих кодов внутри некоторого пространства имен. 1.
В представленном ниже примере иллюстрируются атрибуты демонстрацион-. ных пространств имен. // Демонстрационные пространства имен ((тпс1ис)е <товвгеагв> цв)пя пагпеврасе втг); // определение первого пространства имен пагпеврасе ((гвСМ Ь с)авв г(егло ( 1пг з.г рц)о1з.с: г(егво(5.п1 х) ( г -- х; гго.'с( веСт(тпС х) ( г = х; Гпл деех () г гесигп г г с)гаг еле(1 = "иллюстрация пространств имен~п" г гпс соглгеегг оггределение второго пространства имен паглеврасе еесопс(КЯ ( (пг х, у; (и( гватп () Самоучитель С++ // расширяем область видимости 1з.гзпй)Я::п)еюо оЬ(10); /* После объявления объекта оЬ, его функции-члены могут использоваться прямо, без какого бы то ни было уточнения пространства имен * соий « "Значение объекта оЬ равно: " « оЬ.9ег1() ' сопГ « епп(1; оЬ.яег1(99); сопп « "теперь значение объекта оЬ равно: " « оЬ.деГ1(); сон « епо11; вво~плм строку ягг в текуцую область видимости цяфпд Й1гяГМЯ::яГг; сонг « ягг; вводппч все пространство имен г1гяйЫ в текуп(ую область видимости пяфпд пагпеярасе Йфгяпг(Я; аког(сооюгег=10п соипьег; соипгег--) соуп « сопппег « сопл « епй1; // используем пространство имен яесопог)Я яесопс)мЯ.":х = 10; яесопп(ЫЯ::у 20; сонг « переменные х, у равшан: ™ << яесопсЫБ::х; сонг « ", " « яесопсЮЯ::у « епе(1; вводим все пространство имен яесопсКЯ в текуцую область видимости пяфп9 паюеярасе яесопсЫЯ; Йеюо хоЬ(х), уоЬ(у); сонг « Значения объектов хоЬ, уоЬ равны: " « хоЬ.део1() сопб « ", " « уоЬ.деГ1() « епо(1; гегцгп 0; После выполнения программы на экран будет выведено следующее: Значение объекта оЬ равно: 10 Теперь значение объекта оЬ равно: 99 Иллюстрация пространств имен 10987 б54321 Переменные х, у равны: 10, 20 Значения объектов хоЬ, уоЬ равны: 10, 20 Глава 1 3, Пространства имен и другие темы ЭВЭ Программа иллюстрирует одно важное положение: при совместном использовании нескольких пространств имен одно пространство не подменяет другое.
Когда вы вводите некоторое пространство имен в текущую область видимости, его имена просто добавляются в эту область, независимо от того, находятся ли в ней в это время имена из других пространств имен. Таким образом, ко времени завершения программы в глобальное пространство имен были добавлены пространства имен вИ, Пгв1МЯ и весоп6Мв. 2. Как уже упоминалось, пространство имен можно разделить либо между файлами, либо внутри одного файла, тогда содержимое этого пространства имен объединяется. Рассмотрим пример объединения разделенного пространства имен. // Объединение пространства имен Фтпс1пое <товлтеатп> цз1пя патезрасе зМ; патеирасе 1Зепю ш1 а; // объявление переменной а в пространстве имен Вето тпс х; // объквлекие переменной х в глобальном пространстве имен патеврасе Репо 1 пс Ь; // объявление переменкой Ь в пространстве имен оето 1 1п1 патп1) ( иа1пд паптеврасе Велю; а=Ь=х= 100; сои1 « а « " " « Ь « " " « х; тегитп О; В данном примере обе переменные, а и Ь, оказались в одном пространстве имен — пространстве имен Рево, а переменная х осталась в глобальном пространстве имен, 3.
Как уже упоминалось, стандарт Мандата С++ определяет целую библиотеку в собственном пространстве имен вЫ. Именно по этой причине во всех программах этой книги имеется следующая инструкция: ивы.д патеврасе в о; Эта инструкция делает пространство имен М текущим, что позволяет получить прямой доступ к именам функции и классов, определенных в библиотеке языка Б1апдагд С++, без необходимости каждый раз с помощью оператора Самоучитель С++ 390 расширения области видимости уточнять, что используется пространство имен М.
Тем не менее, если пожелаете, можете перед каждым идентификатором ставить имя пространства имен зМ и оператор расширения области видимости ошибки не будет. Например, в следующей программе библиотека языка огапдагс1 С++ не введена в глобальную область видимости. // Явное задание используемого пространства имен Фьпс1иде <1озсгеагв> 1пг гпа1п О с1оиЫе ча1; зЫ::соос « "Введите число: зМ:: сьп » ча1; зсс1:: соус « "Вот ваше число: зсс1::соШ « уа1; гегигп О; Как показано в данной программе, чтобы воспользоваться стандартными потоками ввода и вывода сш и сов1, перед именами этих потоков необходимо явно указывать их пространство имен. Если в вашей программе не предусмотрено широкое использование библиотеки языка агапг1агд С++, вы можете не вводить пространство имен М в глобальную область видимости.
Однако, если в вашей программе содержатся тысячи ссылок на стандартные библиотечные имена, включить в программу идентификатор зЫ гораздо проще, чем добавлять его чуть ли не к каждой инструкции. 4. Если в своей программе вы используете только несколько имен из стандартной библиотеки, может оказаться удобней с помощью инструкции ияпя отдельно задать эти несколько имен. Преимушество такого подхода в том, что указанные имена можно вносить в программу без необходимости их уточнения, и в то же время не нужно вводить всю стандартную библиотеку в глобальное пространство имен. Рассмотрим пример: // Введение в глобальное пространство только нескольких имен $1пс1ис1е <аозггеат> // обеспечение доступа к потокам с1п и сош из1пя зтс1: гсов; нз1па згс1:: сьп; 1в1 гпа1п 1) допЫе ча1; Глава 13.
П ост анства имсиидругие темы 391 сопв « "Введите число: "т с альп>) та1 р соп « "Вот ваше число: сопл « ча1; песптп 0; Первый файл всапъс 1пс соппсеп; чей Г1 () ( соппсет = 99; !т ОК ) Второй файл ехФегп 1пт соуп(ег; чоЫ Г2 () ( соппсеп = 10; /! Ошибка ) Поскольку переменная сонн(ег определена в первом файле, то и использовать ее можно в первом файле. Во втором файле, несмотря на указание в инструкции с переменной совн1ег идентификатора ех3егв, попытка использования этой переменной ведет к ошибке.
Объявляя в первом файле переменную соипгег статической, мы ограничиваем ее область видимости этим файлом. Хотя объявления глобальных переменных с идентификатором в(а6с в С++ по-прежнему доступны, для достижения той же цели здесь имеется лучший путь — использовать, как показано в следующем примере, безымянное пространство имен. Второй файл ехгегп (пг соцп(ег; чо1о Г2 () ( соппвет = 10; !! Ошибка Первый файл пагпезрасс ( 1пт соиптег; чоЫ т1О соиптсг = 99; // ОК Здесь стандартными потоками ввода и вывода с(н и совт можно пользоваться напрямую, но в то же время остальные имена из пространства имен вИ оставлены вне текущей области видимости.