Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП.doc
Скачиваний:
77
Добавлен:
07.03.2016
Размер:
1.78 Mб
Скачать

9.4 Шаблони та модульність. Простір імен

Шаблони не можна ділити на інтерфейс та реалізацію і транслювати окремо. Шаблон є тільки заготівкою для побудови коду: поки шаблон не інстанційований ("конкретизований конкретним типом"), об'єктний код з нього не транслюється – складальникові нічого робити. Модулі, що використовують шаблон повинні підключити файл з повним визначенням шаблону за допомогою #include. Такий спосіб організації коду з шаблонами називається моделлю включення.

Другий варіант організації коду з шаблонами – модель явного інстанціювання. Цей спосіб працює і для шаблонів функцій, і для шаблонів класів. В цьому випадку шаблони інстанціюються (тобто реалізуються, конкретизуються) за допомогою директиви явного інстанціювання.

Тут клас-шаблон, як і звичайний клас, ділиться на інтерфейс і реалізацію, і в проект включаються наступні файли:

  • файл з визначенням інтерфейсу класу-шаблону;

  • файл з реалізацією класу-шаблону;

  • файл з директивами явного інстанціювання;

  • файл з програмою-клієнтом.

Ділення програми на файли-модулі – це фізичне розділення програми на частини. Щоб розділити велику програму на логічно зв'язані частини, до C++ передбачені простори імен. У новому стандарті визначений стандартний простір імен std.

Простір імен може мати ім'я. Оголошення простору імен – це призначення імені для області, в якій будуть видні компоненти простору імен. Синтаксис іменованого оголошення виглядає так:

namespace ім'я

{ // оголошення і визначення

}

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

У простір імен можна включати і заголовні файли, наприклад:

namespace SPACE { #include "List.h" }

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

<простір імен>::<ім’я компоненту>

Наприклад, імена із стандартного простору імен можна писати так:

std::cin

std::cerr

Щоб не супроводжувати імена кваліфікаторами, можна використовувати using-об’яви

using <простір імен>::<ім’я компоненту>

Слово using, так само як і namespace, є зарезервованим словом. Надалі оголошені імена можна використовувати в програмі без кваліфікатора. Для стандартних імен з простору std це виглядає так:

using std::cout;

using std::endl;

Можна оголосити доступним відразу весь простір імен за допомогою using-директиви

using namespace <простір імен>;

Надалі всі імена з вказаного простору імен можна писати без префікса. Ця директива діє до кінця одиниці трансляції. На інші файли її вплив не розповсюджується. Для використання будь-якого імені із стандартного простору імен std потрібно задати директиву

using namespace std;

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

Будь-яку форму using можна використовувати усередині деякого простору імен з метою включення в нього імен з іншого простору. Не використовуйте глобальну директиву using в заголовних файлах!

У визначеннях членів імена з того ж простору імен дозволено використовувати без вказівки кваліфікатор – аналогічно тому, як в методах класу дозволено вживати будь-які імена з того ж класу без префікса.

Стандарт C++ дозволяє оголошувати синоніми імен (псевдоніми), наприклад:

namesрасе MFC = Microsoft_Foundation_Class;

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

Простори імен можуть бути вкладеними, наприклад:

namespace External {// зовнішній простір імен

double a;

namespace Internal {// вкладений простір імен

void F() { а=7.2; }// працює External ::а

int a;

void G() { а++; } // працює Internal ::а;

}

}

Для звернення до імен з вкладеного простору слід вказувати подвійний префікс-кваліфікатор, наприклад:

External :: Internal ::F();

Псевдоніми можна призначати і для вкладених просторів імен, наприклад:

namespace Borland_Builder { // зовнішнє

/* члени зовнішнього namespace */

namespace Visual_Component_Library { // вкладене

/* члени внутрішнього namespace */

}

}

// Псевдоніми namespace

// Зовнішній простір

namespace ВВ = Borland_Builder;

// Внутрішній простір задається з кваліфікатором

namespace VCL=Borland_Builder::Visual_Component_Library;