28
ограничивается файлом, в котором они объявляются.
Глобальные переменные и
функции к тому же
подчиняются правилам компоновки для нескольких исходных файлов. Рассмотрим следующую
ситуацию:
// В файле Foo.cpp
typedef int Symbol;
// В файле Bar.cpp
typedef void (*Symbol)();
Никакого конфликта не возникнет, если только по мазохистским соображениям вы не включите один
файл с расширением .срр в другой директивой
#include
.
Символическое имя
Symbol
известно
компилятору лишь в тех исходных файлах, в которых оно встречается, поэтому в разных исходных
файлах его можно использовать по-разному. Следующий фрагмент неверен,
поскольку на этот раз
символическое имя соответствует переменной, а не типу. Имя переменной должно быть уникальным
для всех файлов, передаваемых компоновщику.
// В файле Foo.cpp
int Symbol;
// В файле Bar.cpp
void (*Symbol)();
Единственное исключение из этого правила относится к перегрузке функций, о которой будет
рассказано в следующем разделе. Конечно, конфликты имен часто возникают в любом достаточно
большом проекте, в котором несколько программистов работают над разными исходными файлами.
Одно из возможных решений — использование статических членов; другое — объявление глобальных
переменных и функций статическими. Если переменная или функция объявляется статической, она
определена лишь в границах исходного файла.
// В файле Foo.cpp
static int Symbol;
// В файле Bar.cpp
static void (*Symbol)();
Увидев ключевое слово
static
, компилятор проследит за тем, чтобы компоновщик не перепутал две
разные версии одного символического имени при условии что исходные
файлы не компилируются
вместе; будут сгенерированы две разные переменные.
К любому символическому имени, объявленному в глобальном пространстве имен, можно обратиться с
помощью оператора
::
без указания области действия:
::Fn();
//
Вызвать глобальную функцию с заданным именем
int x = ::i;
// Присвоить x значение глобальной переменной
::SomeType y;
// Использовать глобально объявленный тип
Явно заданная область действия всегда отменяет все символические имена, определенные локально —
например, внутри блока или класса.
Перегрузка
В C++ существует несколько способов многократного использования имен функций. В частности,
пространства имен функций формируются на основе классов. Одноименные функции в классах, не
связанных друг с другом, выполняют совершенно разные задачи. Перегрузка функций развивает
великую традицию разделения пространств имен функций и позволяет
многократно использовать
имена функций в границах одной области действия.
Аргументы
Две функции с одинаковыми именами считаются разными, если они отличаются по количеству,
порядку или типу аргументов.
void Fn();