// Правильно 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();