Доступ к элементам именного пространства через квалифицированные имена




Строка 35 выводит значение переменной doublelnUnnamed, которая доступна непосредственно как входящая в неименованное пространство имен. Строка 38 выводит значение переменной integer1. Для обеих этих переменных компилятор сначала пытается найти локальное объявление в main. Поскольку локальные объявления отсутствуют, компилятор полагает, что эти переменные находятся в глобальном именном пространстве.

Строки 41-43 выводят значения PI, E, integerl и FISCAL3 из именного пространства Example. Заметьте, все они должны иметь квалификатор Example::, поскольку в программе отсутствуют какие-либо директивы или объявления using, сообщающие, что она будет использовать элементы Example. Кроме того, элемент integerl должен квалифицироваться потому, что то же имя имеет глобальная переменная. Иначе выводилось бы значение глобальной переменной. Заметьте, что элемент FISCAL3 является элементом вложенного пространства имен, поэтому он должен квалифицироваться как Example::Inner::. Функция printValues (определенная в строках 50-56) является элементом Example, и потому может обращаться к другим элементам именного пространства Example непосредственно, без указания квалификатора. Оператор вывода в строках 52-55 выводит integerl, PI, E, doubleUnnamed, глобальную переменную integerl и FISCAL3. Заметьте, что PI и Е не квалифицируются. Переменная doubleUnnamed также доступна, поскольку она принадлежит неименованному пространству имен и ее имя не вступает в конфликт с какими-либо элементами именного пространства Example. Глобальная версия integerl должна квалифицироваться унарной операцией разрешения области действия (::), поскольку ее имя конфликтует с элементом именного пространства Example. Кроме того, FISCAL3 необходимо квалифицировать префиксом Inner::. При обращении к элементам вложенного пространства имен они должны квалифицироваться его именем (если только элемент не используется внутри вложенного пространства имен).

 

Пример пространства имен

Пример 7

Рассмотрим пример многофайловой программы, демонстрирующей некоторые возможности пространства имен. Первый файл (namesp.h) является заголовочным и содержит типичные для таких файлов элементы — константы, определения структур и прототипы функций. В этом случае элементы помещены в два пространства имен. Первое пространство имен, pers, содержит определение структуры Person, а также прототипы функции, которая помещает в структуру имя некоторого лица, и функции, отображающей содержимое структуры. Второе пространство имен, debts, определяет структуру для хранения имени лица и суммы его задолженности. Эта структура использует структуру Person, поэтому пространство имен debts содержит директиву using, которая делает имена пространства pers доступными в debts. Пространство имен debts также содержит ряд прототипов.

Второй файл этого примера (namesp.cpp) следует обычному шаблону, при котором файл исходного кода содержит определения для прототипов функций из заголовочного файла. Имена функций, объявленные в пространстве имен, имеют область видимости пространства имен, поэтому определения должны находиться в том же самом пространстве имен, что и объявления. Это тот случай, когда открытая природа пространства имен становится удобной. Исходные пространства имен включаются с помощью файла namesp.h. Затем файл добавляет определения функций к двум пространствам имен, как показано в листинге namesp.cpp. Кроме того, в файле namesp. cpp демонстрируется обеспечение доступа к элементам пространства имен std с помощью объявления using и операции разрешения контекста.

Наконец, третий файл программы (usenmsp.cpp) представляет собой файл исходного кода, который использует структуры и функции, объявленные и определенные в пространствах имен. В usenmsp.cpp показаны методы обеспечения доступа к идентификаторам пространства имен.

Функция main () начинается с двух объявлений using:

 

using debts::Debt; // делает доступным определение структуры Debt

using debts::showDebt; // делает доступной функцию showDebt

 

Обратите внимание, что в объявлениях using присутствуют только имена. Так, во втором примере отсутствует описание типа возвращаемого значения и сигнатуры функции showDebt, а приводится лишь ее имя. (Таким образом, если функция была перегружена, одно объявление using обеспечит импортирование всех ее версий.) Кроме того, хотя Debt и showDebt () используют тип Person, нет необходимости им портировать какое-либо из имен Person, т.к. в пространстве имен debt уже содержится директива using, включающая пространство имен pers.

Функция other () использует менее желательный способ импорта всего пространства имен с помощью директивы using:

 

using namespace debts; // делает доступными для other () все имена из debts и pers

 

Поскольку директива using в debts импортирует пространство имен pers, функция other () может использовать тип данных Person и функцию showPerson ().

Наконец, в функции another () применяется объявление using и операция разрешения контекста для доступа к отдельным именам:

 

using pers::Person;

pers::showPerson(collector);

 

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2019-06-16 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: