Программирование. Принципы и практика использования C++ Исправленное издание, стр. 406
• Локальная область видимости (local scope). Имя находится в локальной области видимости, если она объявлена в функции (включая параметры функции).
• Область видимости класса (class scope). Имя находится в области видимости класса, если оно является именем члена этого класса.
• Область видимости инструкции (statement scope). Имя находится в области видимости инструкции, если оно объявлено в части (
...forwhileswitchifОбласть видимости переменной распространяется (исключительно) до конца инструкции, в которой она объявлена. Рассмотрим пример.
for (int i = 0; i<v.size(); ++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.4.2. Класс памяти
Существуют три класса памяти (раздел 17.4).
• Автоматическая память (automatic storage). Переменные, определенные в функциях (включая параметры функции), размещаются в автоматической памяти (т.е. в стеке), если они явно не объявлены с помощью ключевого слова
static• Статическая память (static storage). Переменные, объявленные в глобальной области видимости и в области видимости пространства имен, хранятся в статической памяти, как и переменные, явно объявленные с помощью ключевого слова
static• Свободная память (куча) (free store (heap)). Объекты, созданные с помощью оператора
newРассмотрим пример.
vector<int> vg(10); // создается один раз при старте программы // ("до функции main()")vector<int>* f(int x){ static vector<int> vs(x); // создается только при первом // вызове f() vector<int> vf(x+x); // создается при каждом вызове f() for (int i=1; i<10; ++i) { vector<int> vl(i); // создается на каждой итерации // ... } // переменная v1 уничтожается здесь (на каждой итерации) return new vector<int>(vf); // создается в свободной памяти // как копия переменной vf} // переменная vf уничтожается здесьvoid ff(){ vector<int>* p = f(10); // получает вектор от функции f() // .. . delete p; // удаляет вектор, полученный от // функции f}Переменные
vgvsmain()Память для членов класса отдельно не выделяется. Когда вы размещаете объект где-то, то нестатические члены размещаются там же (в том же классе памяти, что и сам объект, которому они принадлежат).
Код хранится отдельно от данных. Например, функция-член не хранится в каждом объекте своего класса; одна ее копия хранится вместе с остальной частью кода программы.
См. также разделы 14.3 и 17.4.
A.4.3. Время жизни
Перед тем как объект будет (легально) использован, он должен быть проинициализирован. Эту инициализацию можно осуществить явно, с помощью инициализатора, или неявно, используя конструктор или правило инициализации объектов встроенных типов по умолчанию. Время жизни объекта заканчивается в точке, определенной его областью видимости и классом памяти (например, см. разделы 17.4 и Б.4.2).
• Локальные (автоматические) объекты создаются, когда поток выполнения достигает их определения, и уничтожаются при выходе из области видимости.
• Временные объекты создаются конкретным подвыражением и уничтожаются по завершении полного выражения. Полное выражение — это выражение, которое не является подвыражением другого выражения.
• Объекты в пространстве имен и статические члены классов создаются в начале программы (до функции
main()main()• Локальные статические объекты создаются, когда поток выполнения достигает их определения и (если они были созданы) уничтожаются в конце программы.
• Объекты в свободной памяти создаются оператором
newdelete