Литмир - Электронная Библиотека
A
A

Заголовки обычно включаются во многие исходные файлы. Это значит, что заголовок должен содержать лишь объявления, которые можно дублировать в нескольких файлах (например, объявления функций, классов и числовых констант). 

8.4. Область видимости

Область видимости (scope) — это часть текста программы. Каждое имя объявляется в своей области видимости и является действительным (т.е. находится в области видимости), начиная с точки объявления и заканчивая концом данной области. Рассмотрим пример.

void f()

{

  g();       // ошибка: g() не принадлежит (пока) области видимости

}

void g()

{

  f();       // OK: функция f() находится в области видимости

}

void h()

{

  int x = y; // ошибка: переменная y не принадлежит (пока)

             // области видимости

  int y = x; // OK: переменная x находится в области видимости

  g();       // OK: функция g() находится в области видимости

}

Имена, принадлежащие области видимости, видны из вложенных в нее других областей видимости. Например, вызов функции

f()
находится в области видимости функции
g()
, которая является вложенной в глобальную область видимости. Глобальная область видимости не вкладываются ни в какую другую. Правило, утверждающее, что имя должно быть объявлено до того, как будет использовано, по-прежнему действует, поэтому функция
f()
не может вызывать функцию
g()
.

Существует несколько разновидностей областей видимости, которые можно использовать для управления используемыми именами.

Глобальная область видимости (global scope). Часть текста, не входящая ни в одну другую область видимости.

Пространство имен (namespace scope). Именованная область видимости, вложенная в глобальную область видимости или другое пространство имен (раздел 8.7).

Область видимости класса (class scope). Часть текста, находящаяся в классе (раздел 9.2).

• Локальная область видимости (local scope). Часть текста, заключенная в фигурные скобки, { ... }, в блоке или функции.

• Область видимости инструкции (например, в цикле

for
).

Основное предназначение области видимости — сохранить локальность имен, чтобы они не пересекались с именами, объявленными в другом месте. Рассмотрим пример.

void f(int x)  // функция f является глобальной;

               // переменная x является локальной в функции f

{

  int z = x+7; // переменная z является локальной

}

int g(int x)   // переменная g является глобальной;

               // переменная x является локальной в функции g

{

  int f = x+2; // переменная f является локальной

  return 2*f;

}

Изобразим это графически.

Программирование. Принципы и практика использования C++ Исправленное издание - _065.png

Здесь переменная

x
, объявленная в функции
f()
, отличается от переменной
x
, объявленной в функции
g()
. Они не создают недоразумений, потому что принадлежат разным областям видимости: переменная
x
, объявленная в функции
f()
, не видна извне функции
f()
, а переменная
x
, объявленная в функции
g()
, не видна извне функции
g()
. Два противоречащих друг другу объявления в одной и той же области видимости создают коллизию (clash). Аналогично, переменная
f
объявлена и используется в функции
g()
и (очевидно) не является функцией
f()
.

Рассмотрим логически эквивалентный, но более реальный пример использования локальной области видимости.

int max(int a, int b) // функция max является глобальной;

                      // а переменные a и b — локальными

{

  return (a>=b) ? a : b;

}

int abs(int a)        // переменная a, не имеющая отношения

                      // к функции max()

{

  return (a<0) ? –a : a;

}

Функции

max()
и
abs()
принадлежат стандартной библиотеке, поэтому их не нужно писать самому. Конструкция
?:
называется арифметической инструкцией if (arithmetic if), или условным выражением (conditional expression). Значение инструкции (
a>=b)?a:b
равно
a
, если
a>=b
, и
b
— в противном случае. Условное выражение позволяет не писать длинный код наподобие следующего:

int max(int a, int b) // функция max является глобальной;

                      // а переменные a и b — локальными

{

  int m; // переменная m является локальной

  if (a>=b)

    m = a;

  else

   m = b;

  return m;

}

 

Программирование. Принципы и практика использования C++ Исправленное издание - _001.png
 Итак, за исключением глобальной области видимости все остальные области видимости обеспечивают локальность имен. В большинстве случаев локальность имени является полезным свойством, поэтому к нему надо стремиться изо всех сил. Когда мы объявляем свои переменные, функции и прочее в функциях, классах, пространствах имен и так далее, то не хотим, чтобы они совпадали с именами, объявленными кем-то другим. Помните: реальные программы содержат многие тысячи именованных сущностей. Для того чтобы сохранить контроль над такими программами, большинство имен должно быть локальными.

110
{"b":"847443","o":1}