- локальная область видимости;
- область видимости класса;
- пространство имен;
- область видимости файла.
Локальная область видимости
Локальная область видимости – это область видимости внутри блока.
Каждая функция – это отдельная область видимости. Внутри функции может быть несколько блоков, заключенных в фигурные скобки {…}, также образующих отдельные области видимости. Для переменных, объявленных в блоке, область видимости – от точки объявления до конца блока.
{
тело цикла;
}
// переменная i недоступна
Область видимости класса
Каждый класс представляет отдельную область видимости. Имена членов класса локальны в этом классе. Область видимости полей и методов класса (член-данных и член-функций) не зависит от точки их объявления, то есть член класса виден во всем классе. Каждый метод определяет свою собственную локальную область видимости, аналогично обычной функции. Можно явно указать область видимости в С++, используя оператор разрешения контекста (области видимости) ::.
Оператор разрешения контекста имеет самый высокий приоритет и применяется в двух формах:
- унарная — ссылается на внешний контекст;
- бинарная — ссылается на контекст класса.
Унарная форма записи:
:: Идентификатор
Бинарная форма записи:
ИмяКласса :: Идентификатор
Унарная форма используется для обращения к имени, относящемуся ко внешнему контексту и скрытому локальным контекстом или контекстом класса.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
int count = 0; // (*)
void func(void)
{
for (int count = 0; count < 10; count++)
{
++ ::count; // увеличивает на 1 (*)
}
}
int main()
{
cout << "count =" << ::count << endl;
func();
cout << "count =" << ::count << endl;
cin.get();
return 0;
}
Результат выполнения
Бинарная форма используется для ссылки на контекст класса с целью устранения неоднозначности имен, которые могут повторно использоваться внутри класса.
2
3
4
class cl2 {void f() {…} …};
cl1 :: f(); // обращение к f() из cl1
cl2 :: f(); // обращение к f() из cl2
Классы могут быть вложенными. Правила видимости для вложенных классов рассмотрим на примере.
Пример
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
using namespace std;
int c; // внешняя область (контекст)
class X // внешнее объявление класса
{
public:
static int c;
class Y // внутренне объявление класса
{
public:
static int c;
static void f(int key)
{
::c = key; // внешняя переменная
X::c = key + 1; // переменная c класса X
c = key + 2; // переменная c класса Y
}
};
};
int X::c = 0;
int X::Y::c = 0;
int main()
{
X::Y::f(3);
cout << " c = " << c << endl;
cout << "X::c = " << X::c << endl;
cout << "Y::c = " << X::Y::c << endl;
cin.get();
return 0;
}
Результат выполнения
С++ дает возможность создавать вложенные методы с использованием вложенных классов. Это ограниченная форма вложенности функций. Методы должны определяться внутри локального класса, и на них нельзя ссылаться внутри этого контекста. Как и в Си, обычные вложенные функции запрещены. Вложенный класс не находится в области действия включающего его класса.
Пространства имен
Области видимости могут быть вложенными.
Для разделения областей видимости используются так называемые пространства имен.
Пространство имён (namespace) — это некоторое множество, под которым подразумевается модель, абстрактное хранилище или окружение, созданное для логической группировки уникальных идентификаторов (имен).
Объявление пространства имен имеет синтаксис:
{
Содержимое
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
int X = 100; // глобальное пространство имен
namespace A // пространство имен A
{
int X = 10;
namespace B // пространство имен B
{
int X = 20;
}
}
int main() {
int X = 1;
cout << "X = " << X << endl;
cout << "A::X = " << A::X << endl;
cout << "A::B::X = " << A::B::X << endl;
cout << "::X = " << ::X << endl;
cin.get();
return 0;
}
Скажите, пожалуйста, зачем в примере об унарной форме обращения в функции main () используете оператор ввода:
cin.get();
без него ничего не меняется.
Спасибо.
cin.get() нужен если программу запускать в консоли Windows. Без него консоль сразу закроется, и мы не увидим результат.
Подскажите, если в первом примере, при выводе, вместо "cout << ::count…" написать "cout << count", ведь тоже ничего не изменится?
Не изменится