Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lektsii_OP / T12.doc
Скачиваний:
96
Добавлен:
17.03.2016
Размер:
272.38 Кб
Скачать

Область дії та простір імен

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

З концепцією області видимості у сучасних мовах програмування тісно пов'язане поняття простору імен.

Простір імен (namespace) — це іменована область пам’яті, що служить для оголошення унікальних ідентифікаторів. Використання простору імен дає змогу обмежити доступ до логічно згрупуваних оголошень.

Простори імен слугують для розв'язання конфліктів імен у модульних програмах, що складаються з декількох файлів.

По замовчуванню всі ідентифікатори такої програми знаходяться в глобальному просторі імен, тому часті випадки існування двох різних об'єктів з однаковими іменами, що призводить до помилок. Щоб цьому запобігти глобальний простір імен ділять на іменовані області.

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

Окрім того, здебільшого, у кожному завершеному фрагменті програми можна виокремити інтерфейсну частину (наприклад заголовки функцій, опис типів), потрібну для використання цього фрагмента, і частину реалізації, тобто допоміжні змінні, функції та інші засоби, доступ до яких зовні не потрібний. Простори імен дозволяють приховати деталі реалізації і в такий спосіб спростити структуру програми та зменшити кількість потенційних помилок. Добре помірковане розбиття програми на модулі, чітка специфікація інтерфейсів і обмеження доступу дозволяють організу-вати ефективну роботу над проектом групи програмістів.

Таким чином, ідентифікатори в одному просторі імен (одній зоні видимості) повинні бути унікальними, але в різних областях вони можуть і збігатися. Імена, оголошені поза всіма зонами видимості, входять в глобальний простір імен.

Оголошення простору імен здійснюється наступним чином.

namespace ім’я_простору

{ послідовність оголошень та визначень

}

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

Наприклад,

namespace mySpace

{ int n;

}

Тут ідентифікатор n оголошений і доступний для використання всередині простору mySpace. Однак до нього можна явно звертатися і поза межами цього простору. Для такого звертання служить так зване кваліфіковане ім’я об’єкта, яке формується оператором доступу до області видимості "::" і складається з двох частин: кваліфікатора (імені) простору і локального імені в межах цього простору:

ім’я_простору :: ідентифікатор_об’єкта.

Наприклад, щоб присвоїти значення 10 змінній n в тій частині програми, яка не входить до простору імен mySpace, потрібно використати наступну конструкцію:

mySpace:: n = 10;

Ідентифікатор n, оголошений всередині простору mySpace, для компілятора задається глобальним ідентифікатором mySpace::n. Вираз mySpace::n розуміють як "ім’я n, оголошене в просторі mySpace".

У межах простору mySpace компілятор "розуміє" як локальне ім’я n, так і кваліфіковане mySpace::n, але за межами цього простору діє лише кваліфіковане ім’я mySpace::n. Іншими словами, областю дії оголошення імені n є простір mySpace, тому за його межами це оголошення діяти не повинно. Завдяки тому, що область дії оголошення імені обмежено простором імен, однакові імена, оголошені в різних просторах, стають для компілятора різними. Саме це й дозволяє уникати конфліктів імен.

В оголошенні простору імен можуть бути присутні як оголошення, так і визначення. Наприклад,

namespace mySpace

{ int name, // оголошення змінної

i= 1; // визначення змінної

void func1(int); // оголошення функції

void func2(int j) { cout << j; } // визначення функції

}

Однак, логічно розміщувати у ньому лише оголошення, а визначати їх пізніше за допомогою кваліфікованих імен. Наприклад,

void mySpace:: func2(int)

{ …

}

Такий підхід застосовується для розділення інтерфейсу і реалізації.

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

  1. using namespace ім’я_простору;

  2. using ім’я_простору::об'єкт;

У першій формі інструкції using всі члени, оголошені у вказаному просторі імен, стають доступними в поточному просторі імен і з ними можна працювати безпосередньо, без необхідності кожного разу вказувати ім'я простору і оператор розширення області видимості. Наприклад,

using namespace mySpace;

При використанні другої форми інструкції using в поточному просторі імен робиться видимим тільки вказаний член заданого простору імен. Наприклад,

using mySpace:: n.

Оператори using та using namespace можна використовувати всередині простору імен, щоб зробити в ньому доступними оголошення з іншої області. Наприклад,

namespace Department

{ using mySpace:: i;

. . .

}

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

Короткі імена просторів імен можуть увійти у конфлікт один з одним, а довгі є непрактичними при написанні реального коду, тому дозволяється вводити синоніми таких імен. Наприклад,

namespace DAM = Department_of_Informational_Technologies;

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

Розглянемо приклад використання декількох просторів імен.

Відомо, що в метричній системі префікс «кіло» задає множення на 103, але у випадку вимірювання обсягу інформації програмісти використовують цей префікс для множення на 210. Нехай є cpp-файли (та відповідні h-файли), кожен з яких містить функцію kilo для перетворення одиниці вимірювання «кіло» в прості одиниці. Відмінність між цими двома файлами лише в тому, що в першому функція виконує множення на відповідну степінь 10, а в другому — на степінь 2. Припустимо, що в програмі необхідні функції з обох файлів. Спроба включити обидва цих cpp-файли в проект буде неуспішною, оскільки функція kilo буде мати в проекті два означення (у таких ситуаціях кажуть, що виник конфлікт імен). Уникнути цих проблем можна, якщо скористатися простором імен.

Уведемо два простори імен функцій: metric — для обчислень за метричною системою, binary — за двійковою системою.

Функцію простору binary оголосимо у файлі prefix2.h.

namespace binary

{ double kilo (double x); //*1024

}

У файлі prefix2.cpp запишемо означення функції (також у просторі):

namespace binary

{ double kilo (double x)

return x*1024;

}

Так само, у файлі prefix10.h оголосимо функцію простору metric:

namespace metric

{ double kilo (double x); //*1000

}

У файлі prefix10.cpp запишемо її означення:

namespace metric

{ double kilo (double x)

return x*1000;

}

Проілюструємо використання розроблених cpp-файлів простою програмою.

#include <iostream>

#include "prefix2.h"

#include "prefix10.h"

using namespace std;

int main()

{ cout <<"1 Kg = "<< metric::kilo(1) << " gramme"<< endl; // 1000

cout <<"1 Kb = "<< binary::kilo(1) << " byte"<< endl; // 1024

system("pause");

}

У наведеній програмі, як і у більшості програм на С++, використовується інструкція

using namespace std;

яка робить доступними для явного використання всі імена стандартного простору імен std. У даному просторі імен визначено всі об'єкти стандартної бібліотеки C++, зокрема, стандартні потоки вводу–виводу cin, cout. Без використання цієї інструкції їх довелося б задавати як std::cin і std::cout відповідно.

Також у просторі імен std визначені і об’єкти стандартної бібліотеки STL.

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

1Зарезервоване слово static має декілька значень залежно від контексту. У контексті глобальних змінних воно звужує область видимості змінної до одного файла.

2Колекція, на відміну від контейнера, в загальному випадку, допускає явне задання числа елементів

18

Соседние файлы в папке lektsii_OP