// Правильно Outer::Inner::AFunc() ;

}

Несколько важных замечаний в связи с данным примером вложения пространств. Прежде всего, отметим сходство этого примера с примером из листинга 24.2. Там были определены две подобласти видимости и каждая подобласть была вложена в main ().

В данном примере такая же структура, и это имеет свои минусы, и свои плюсы. Пространство inner имеет ничем не ограниченный доступ к переменной Dog из пространства Outer. В то же время в пространстве inner переменная cat из пространства-родителя скрыта определением собственной переменной Cat.

На первый взгляд может показаться, что пространства имен страдают от той же проблемы сокрытия имен, которая отмечалась в листинге 24.2. В целом это верно для большинства ситуаций, но давайте рассмотрим подробнее определение функции AFunc ().

// Выведем их всех по порядку

void AFunc()

(

cout « "Cat: " « Cat « "\n"; // Это Inner::Cat

cout « "Inner Cat: " « Inner: : Cat « "\n";

cout « "Outer Cat: " « Outer::Cat « "\n";

)

Действительно, при выводе переменной cat без уточнения программист получит версию из inner, которая скрывает версию, определенную в Outer. Опытный программист в простейшем случае, подобном этому примеру, может спокойно использовать переменные без уточнения.

С другой стороны, при наличии пространств имен есть возможность точно указывать, какая из переменных cat используется. Именно это и делается в функции AFunc () для вывода обеих версий cat из inner и outer. Можно выбрать себе за правило всегда указывать уточнение. Это потребует, может быть, нескольких дополнительных секунд при кодировании, но такая мелочь не может сравниться с временем, затраченным на поиски ошибок, вызванных случайным использованием ошибочной версии переменной.

Необходимо также помнить, что при уточнении должны быть указаны все промежуточные имена пространств. Функция main о из листинга 24.7 именно так и поступает:

void main() {

// Ошибка — AFunc() недоступна в Outer

// Outer::AFunc();