
- •3. Структура главного файла проекта
- •1.8 Области видимости переменных и функций
- •1.8.1 Правила, определяющие область видимости
- •62 Глава 1
- •5. Обработка исключений в блоках try ... Catch
- •2.10.1 Файловый ввод/вывод с помощью компонентов
- •2.14.1 Объявление класса
- •186 Глава 2
- •188 Глава 2
- •244 Глава 3
62 Глава 1
Подчеркнем, что таким образом можно получить доступ только к одноимен-
ной глобальной переменной, а не к локальной переменной, описанной во внешнем
блоке.
Единственными идентификаторами с областью действия прототип функции
являются те, которые используются в списке параметров прототипа функции (см.
разд. 1.7.1). Прототипы функций не требуют имен в списке параметров — требу-
ются только типы. Если в списке параметров прототипа функции используется
имя, компилятор это имя игнорирует. Идентификаторы, используемые в прототи-
пе функции, можно повторно использовать где угодно в программе, не опасаясь
двусмысленности.
Теперь остановимся на проблемах видимости переменных в приложениях,
имеющих несколько модулей. Пусть вы имеете два модуля — Unitl и Unit2 и хо-
тите в модуле Unit2 видеть и использовать переменные и функции, объявленные
в модуле Unitl. Вы можете в модуле Unit2 видеть те переменные, которые являют-
ся глобальными в модуле Unitl, т.е. объявлены вне каких-нибудь функций в заго-
ловочном файле модуля или в его файле реализации. Но для того, чтобы это было
возможно, вы должны повторно объявить их (без инициализации) в модуле Unit2
со спецификацией extern. Например, если в модуле Unitl имеется объявление гло-
бальной переменной
int al = 10;
то в модуле Unit2 вы можете использовать эту переменную, если запишете объяв-
ление
extern int al;•
Причем, это не зависит от того, включили ли вы директивой #include заголо-
вочный файл Unitl.h в модуль Unit2, или нет.
Отметим еще одну особенность использования переменных, описанных в дру-
гом модуле. Если в заголовочном модуле Unitl объявлена описанная выше пере-
менная al, а в модуле Unit2 вы включили директивой #include заголовочный
файл Unitl.h, но не записали объявление этой переменной со спецификацией
extern (вообще не дали объявление al), то в модуле Unit2 будет создана копия пе-
ременной al, инициализированная согласно объявлению в Unitl. Но это будет ко-
пия, совершенно изолированная от переменной al в модуле Unitl. В модулях
Unitl и Unit2 будут существовать две различные переменные с одним именем al.
И изменение одной из них никак не скажется на значении другой.
Все сказанное относится только к глобальным переменным.Локальные пере-
менные, объявляемые внутри функций, невозможно видеть в другом модуле.
Теперь рассмотрим видимость функций в приложениях, имеющих несколько
модулей. Если в модуле Unitl в еш заголовочном файле вне описания класса вы
объявили некоторую функцию F, то в другом модуле Unit2 вы можете использо-
вать ее при выполнении одного из двух условий:
• вы включаете директивой #include в модуль Unit2 заголовочный файл
Unitl.h
• вы повторяете в модуле Unit2 (в заголовочном файле или файле реализации)
объявление функции F
В обоих случаях вы сможете вызвать функцию F из любого места модуля
Unit2.
Если же функция F объявлена в модуле Unitl не заголовочном файле, а в фай-
ле реализации, то единственный способ использовать ее в модуле Unit2 — повто-
рить в нем объявление функции.
Если вы хотите предотвратить возможность обращения к функции из другого
модуля, ее надо объявить со спецификацией static. Например:
static void F(void);
Справочные данные по языку C++ 63
Подведем некоторые итоги проведенного рассмотрения проблем видимости пе-
ременных и функций.
• Переменные, объявленные в заголовочном файле модуля или в файле его реа-
лизации вне описания класса и функций, являются глобальными. Они доступ-
ны везде внутри данного модуля. Для доступа к ним из внешних модулей
в этих модулях должно быть повторено их объявление (без инициализации)
с добавлением спецификации extern.
• Функции, объявленные в заголовочном файле модуля вне описания класса,
являются глобальными. Они доступны везде внутри данного модуля. Для до-
ступа к ним из внешних модулей в этих модулях или надо повторить их объяв-
ление, или включить директивой #include заголовочный файл того модуля,
в котором функции описаны.
• Функции, объявленные в файле реализации модуля, являются глобальными.
Они доступны везде внутри данного модуля. Для доступа к ним из внешних
модулей в этих модулях надо повторить их объявление.
• Элементы (переменные и функции), объявленные в классе в разделе private,
видимы и доступны только внутри данного модуля. При этом из функций,
объявленных внутри класса, к ним можно обращаться непосредственно по
имени, а из других функций — только со ссылкой на объект данного класса.
Если в модуле описано несколькоклассов, то объекты этих классов взаимно
видят элементы, описанные в их разделах private.
• Элементы, объявленные в классе в разделе public, видимы и доступны для
объектов любых классов и для других модулей, в которых директивой #include
включен заголовочный файл данного модуля. При этом из объектов того же
класса, к ним можно обращаться непосредственно по имени, а из других объ-
ектов и процедур — только со ссылкой на объект данного класса.
• В классах, помимо обсуждавшихся ранее, могут быть еще разделы protected
— защищенные. Элементы, объявленные в классе в разделе protected, ви-
димы и доступны для любых объектов внутри данного модуля, а также для
объектов классов — наследников данного класса в других модулях. Объекты
из других модулей, классы которых не являются наследниками данного клас-
са, защищенных элементов не видят.
• Элементы, объявленные внутри функции или блока, являются локальными,
т.е. они видимы и доступны только внутри данной функции или данного бло-
ка. При этом время жизни переменных, объявленных внутри функции или
блока, определяется временем активности данного блока. Сделать локаль-
ную переменную существующей постоянно можно с помощью спецификации
static.
• Переменные и функции, объявленные в головном файле проекта, являются
глобальными для этого файла. Если требуется доступ к ним из других моду-
лей, то для функций в них должны быть повторены их объявления, а для пе-
ременных — повторено объявление (без инициализации) со спецификацией
extern.
• Если во внутреннем блоке объявлена переменная с тем же именем, что во
внешнем блоке, или с тем же именем, что и глобальная переменная, то соот-
ветствующая внешняя или глобальная переменная в блоке не видна. В этом
случае подучить доступ к одноименной глобальной переменной можно только
с помощью унарной операции разрешения области действия "::".