Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
7
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

21.1.3. Неіменовані простори імен

Існує неіменований простір імен спеціального типу, який дає змогу створювати ідентифікатори, унікальні для цього файлу. Загальний формат його оголошення має такий вигляд:

namespace {

// Оголошення

}

Неіменовані простори імен дають змогу встановлювати унікальні ідентифікатори, які відомі тільки в області видимості одного файлу. Іншими словами, члени файлу, який містить неіменований простір імен, можна використовувати безпосередньо, без уточнюючого префікса. Але поза файлом ці ідентифікатори є невідомими.

Неіменований простір імен обмежує ідентифікатори рамками файлу, у якому їх оголошено.

Як ми вже зазначали вище у цьому навчальному посібнику, використання модифікатора типу static також дає змогу обмежити область видимості глобального простору імен файлом, у якому він оголошений. Наприклад, розглянемо такі два файли, які є частиною однієї і тієї ж самої програми:

Файл One

Файл Two

static int kzm;

void fun_1() {

kzm = 99; //OK

}

extern int kzm;

void fun_2() {

kzm = 10; // помилка

}

Оскільки змінну kzm визначено у файлі One, то її і можна використовувати у файлі One. У файлі Two змінну kzm визначено як зовнішню (extern-змінна), а це означає, що її ім'я і тип відомі, але саму змінну kzm насправді не визначено. Коли ці два файли будуть скомпоновані, спроба використовувати змінну kzm у файлі Two призведе до виникнення помилки, оскільки у ньому немає визначення для змінної kzm. Той факт, що kzm оголошена як static-змінна у файлі One, означає, що її область видимості обмежується цим файлом, і тому вона недоступна для файлу Two.

Незважаючи на те, що використання глобальних static-оголошень все ще дозволено стандартом мови програмування C++, проте для локалізації ідентифікатора у межах одного файлу краще використовувати неіменований простір імен. Розглянемо такий приклад:

Файл One

Файл Two

namespace {

int kzm;

}

static int kzm;

void fun_1() {

kzm = 99; // OK

}

extern int kzm;

void fun_2() {

kzm = 10; // помилка

}

Тут змінну kzm також обмежено рамками файлу One. Для нових програм рекомендується використовувати замість модифікатора static неіменований простір імен.

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

21.1.4. Застосування простіру імен std

Стандарт мови програмування C++ визначає всю свою бібліотеку у власному просторі імен, який іменується std. Саме з цієї причини більшість програм у цьому навчальному посібнику містять таку настанову:

using namespace std; // Використання стандартного простору імен

У процесі виконання цієї настанови простір імен std стає поточним, що відкриває прямий доступ до імен функцій і класів, визначених у цій бібліотеці, тобто під час звернення до них відпадає необхідність у використанні префікса std::.

Простір імен std використовується власною бібліотекою мови програмування C++.

Звичайно, при бажанні можна безпосередньо кваліфікувати кожне бібліотечне ім'я префіксом std::. Наприклад, наведений нижче код програми не привносить бібліотеку в глобальний простір імен.

Код програми 21.3. Демонстрація механізму використання безпосередньо заданої кваліфікації бібліотечних імен префіксом std::

#include <iostream> // Для потокового введення-виведення

int main()

{

double num;

std::cout << "Введіть число: ";

std::cin >> num;

std::cout << "Ви ввели число ";

std::cout << num;

getch(); return 0;

}

У цій програмі імена cout і cin безпосередньо доповнені іменами своїх просторів імен. Отже, щоб записати дані у стандартний вихідний потік, необхідно використовувати не просто ім'я потоку cout, а ім'я з префіксом std::cout, а щоб зчитати дані із стандартного вхідного потоку, потрібно застосувати "префіксне" ім'я std::cin.

Якщо Ваша програма використовує стандартну бібліотеку тільки в обмежених межах, то, можливо, її і не варто вносити в глобальний простір імен. Але, якщо Ваша програма містить сотні посилань на бібліотечні імена, то набагато простіше зробити простір імен std поточним, ніж повністю кваліфікувати кожне ім'я окремо.

Якщо Ви використовуєте тільки декілька імен із стандартної бібліотеки, то, ймовірно, є сенс використовувати настанову using для кожного з них окремо. Перевага цього підходу полягає у тому, що ці імена можна, як і раніше, використовувати без префікса std::, не вносячи при цьому всю бібліотеку стандартних функцій у глобальний простір імен. Розглянемо такий приклад.

Код програми 21.4. Демонстрація внесення в глобальний простір імен декількох імен

#include <iostream> // Для потокового введення-виведення

// Отримуємо доступ до імен потоків cout і cin

using std::cout;

using std::cin;

int main()

{

double num;

cout << "Введіть число: ";

cin >> num;

cout << "Ви ввели число ";

cout << num;

getch(); return 0;

}

У цій програмі імена потоків cin і cout можна використовувати безпосередньо, але інша частина простору імен std не внесена в область видимості.

Як ми вже зазначали вище, початкова бібліотека мови програмування C++ була визначена в глобальному просторі імен. Якщо Вам доведеться модернізувати старі С++-програми, то програміст повинен або включити в них настанову using namespace std, або доповнити кожне звернення до члена бібліотеки префіксом std::. Це особливо важливо, якщо Вам доведеться замінювати старі заголовні *.h-файли сучасними заголовками.

Необхідно пам'ятати! Старі заголовні *.h-файли поміщають свій вміст у глобальний простір| імен, а сучасні заголовки – у простір імен std.