Читаем Программирование полностью

Каждое имя в языке C++ (за исключением имен препроцессора; см. раздел A.17) имеет определенную область видимости (scope); иначе говоря, существует область текста, в которой его можно использовать. Данные (объекты) хранятся в памяти; вид памяти, используемой для хранения объекта, называется классом памяти (storage class). Время жизни (lifetime) объекта отсчитывается от момента его инициализации до момента окончательного уничтожения. 

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

Существует пять видов областей видимости (см. раздел 8.4).

Глобальная область видимости (global scope). Имя находится в глобальной области видимости, если оно объявлено вне языковой конструкции (например, вне класса или функции).

Область видимости пространства имен (namespace scope). Имя находится в области видимости пространства имен, если оно определено в пространстве имен и вне какой-либо языковой конструкции (например, вне класса и функции). Формально говоря, глобальная область видимости — это область видимости пространства имен с “пустым именем”.

Локальная область видимости (local scope). Имя находится в локальной области видимости, если она объявлена в функции (включая параметры функции).

Область видимости класса (class scope). Имя находится в области видимости класса, если оно является именем члена этого класса.

Область видимости инструкции (statement scope). Имя находится в области видимости инструкции, если оно объявлено в части (...) инструкции for, while, switch или if.


Область видимости переменной распространяется (исключительно) до конца инструкции, в которой она объявлена. Рассмотрим пример.


for (int i = 0; i

  // переменная i может быть использована здесь

}

if (i < 27) // переменная i из инструкции for вышла из области

            // видимости


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


void f();  // в глобальной области видимости

namespace N {

  void f() // в пространстве области видимости N

  {

  int v;   // в локальной области видимости

  ::f();   // вызов глобальной функции f()

  }

}


void f()

{

  N::f();  // вызов функции f(x) из области видимости N

}


Что произойдет, если мы вызовем функции N::f() или ::f()? См. раздел A.15.

A.4.2. Класс памяти

Существуют три класса памяти (раздел 17.4).

Автоматическая память (automatic storage). Переменные, определенные в функциях (включая параметры функции), размещаются в автоматической памяти (т.е. в стеке), если они явно не объявлены с помощью ключевого слова static. Автоматическая память выделяется, когда функция вызывается, и освобождается при возвращении управления в вызывающий модуль. Таким образом, если функция (явно или неявно) вызывает сама себя, может существовать несколько копий автоматических данных: по одной копии на каждый вызов (см. раздел 8.5.8).

Статическая память (static storage). Переменные, объявленные в глобальной области видимости и в области видимости пространства имен, хранятся в статической памяти, как и переменные, явно объявленные с помощью ключевого слова static в функциях и классах. Редактор связей выделяет статическую память до запуска программы.

Свободная память (куча) (free store (heap)). Объекты, созданные с помощью оператора new, размещаются в свободной памяти.


Рассмотрим пример.


vector vg(10); // создается один раз при старте программы

                    // ("до функции main()")


vector* f(int x)

{

  static vector vs(x); // создается только при первом

                            // вызове f()

  vector vf(x+x);      // создается при каждом вызове f()

  for (int i=1; i<10; ++i) {

    vector vl(i);      // создается на каждой итерации

    // ...

  }    // переменная v1 уничтожается здесь (на каждой итерации)

  return new vector(vf); // создается в свободной памяти

                              // как копия переменной vf

} // переменная vf уничтожается здесь


void ff()

{

  vector* p = f(10); // получает вектор от функции f()

  // .. .

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже