Глава 24. Пространства имен 673
II Здесь создается уже другая область
// Она называется В
{
long Dog = 987; // А что это?
long Lizard = 789;
cout « "\nBo второй области:\n";
cout « "Dog равна " « Dog « "\n";
cout « "Lizard равна " « Lizard « "\n";
// Переменная Cat здесь недоступна }
// Обе переменные — Cat и Lizard уже вне области видимости cout « "\пВ области видимости main О :\п";
cout « "Dog равна " « Dog « endl;
)
В данной программе три области видимости: область, созданная функцией main () и две вложенные области, созданные с помощью скобок. Будем называть их области АЙВ, как указано в комментариях.
Поскольку main () включает область А, все, что определено в main (), доступно и в А. Поэтому первая часть нашей программы выводит ожидаемые значения переменных Cat и Dog. Заметим, что cat, определенная внутри А, недоступна В main().
Соотношение области видимости внутри функции main о и области в, на первый взгляд, должно быть таким же. Существует, однако, некоторая разница. Поскольку main () также включает и в, все, что определено в main о, доступно и в в. Так же, как и переменная Cat, переменная Lizard недоступна В main().
Однако — и именно здесь кроется разница — в области в определяется своя переменная Dog. В момент входа в блок в локальная версия Dog (со значением 987) получает преимущество и используется вместо Dog из функции main (). Таким образом, локальная переменная Dog в в скрывает (hides) версию Dog ИЗ main ().
Здесь заключается проблема, которая оказывается более коварной, чем просто конфликт имен. Сокрытие переменных в C++ является на первый взгляд достоинством, а не недостатком языка. Переменные самого нижнего уровня (области видимости) получают преимущество над одноименными переменными верхних уровней, и это соглашение облегчает инкапсуляцию. С другой стороны, также нетрудно вообразить случай, когда программист полагает, что он использует одну переменную (или определение класса, перечисления и т. д.), в то время как в действительности он использует нечто совершенно другое.
Рассмотренный пример намеренно выбран очень простым, однако не нужно быть очень опытным программистом на C++, чтобы понять, как множество
22 Зак. 306