Смекни!
smekni.com

Розробка власного класу STRING (стр. 3 из 16)

Програма на мал.2 використовує клас Time. Ця програма створює єдиний об'єкт класу Time, названий t. Коли об'єкт створюється, автоматично викликається конструктор Time, що явно привласнює нульові початкові значення всім даним-елементам закритої частини private. Потім друкується час у військовому й стандартному форматах, щоб підтвердити, що елементи одержали правильні початкові значення. Після цього за допомогою функцій-елементів setTime встановлюється час і воно знову друкується в обох форматах. Потім функція-елемент setTime намагається дати даним-елементам неправильні значення й час знову друкується в обох форматах.

Знову відзначимо, що дані-елементи hour, minute і second об’явлені специфікатором доступу до елементів private. Ці закриті дані-елементи класу звичайно недоступні поза класом. Глибокий зміст такого підходу полягає в тому, що реальне становище даних усередині класу не стосується клієнтів класу. Наприклад, було б цілком можливо змінити внутрішню структуру даних і представляти, наприклад, час усередині класу як число секунд після опівночі. Клієнти могли б використати ті ж самі відкриті функції-елементи й одержувати ті ж самі результати, навіть не усвідомлюючи про зроблені зміни. У цьому сенсі, говорять, що реалізація класу схована від клієнтів. Таке приховання інформації сприяє модифікаційності програм і спрощує сприйняття класу клієнтами.


// FIG 3. CPP // Клас Time.

#include <iostream. h>

// Визначення абстрактного типу даних (АТД) Time

class Time{

public:

Time{); // конструктор

void setTime (int, int, int); // установка годин, хвилин

// та секунд

void printMilitary (); // часу у військовому форматі

void printStandard (); // друк часу

// у стандартному форматі

private:

int hour; // 0-23

int minute; // 0-59

int second; // 0-59

// Конструктор Time привласнює нульові початкові значення // кожному елементу даних. Забезпечує погоджене

// початковий стан всіх об'єктів

Time Time:: Time () { hour = minute = second =0; }

// Завдання нового значення Time у вигляді воєнного часу. // Перевірка правильності значень даних.

// Обнуління неправельних значень,

void Time:: setTime (int h, int m, int s) {

hour = (h>=0&&h<24)? h: 0;

minute = (m >= 0 && m < 60)? m: 0;

second ~ (s > - 0 && s < 60)? s: Q-; }

// Друк часу у військовому форматі

void Time:: printMilitary ()

{

cout " {hour < 10?"0": "")" hour" ": "

" (minute < 10?"0": "")" minute " ": "

" (second < 10?"0": "")" second; }

// Друк часу в стандартному форматі void Time:: printStandard ()

{

cout " ( (hour == 0 || hour == 12)? 12: hour% 12)

"": " " (minute < 10?"0": "")" minute

"": " " (second < 10?"0": "")" second

" (hour < 12?" AM": " PM");

}

// Формування перевірки простого класу Time

main ()

{

Time t; // визначення екземпляра об'єкта t класу Time

cout " "Початкове значення воєнного часу дорівнює "; t. printMilitary (); cout << endl

<< "Початкове значення стандартного часу дорівнює "; t. printStandard ();

t. setTime (13, 27,6):

cout " endl " endl << "Воєнний час після setTime дорівнює "; t. printMilitary ();

cout << endl << "Стандартний час після setTime дорівнює"; t. printStandard ();

t. setTime (99, 99, 99); // спроба встановити неправильні значення cout << endl << endl

<< "Після спроби неправильної установки: "

<< endl " "Воєнний час: "; t. printMilitary ();

cout << endl " "Стандартний час: "; t. printStandard (); cout << endl; return 0; }

Мал.2. Використання абстрактного типу даних Time як класу


Початкове значення воєнного часу дорівнює 00: 00: 00 Початкове значення стандартного часу дорівнює 12: 00: 00 AM

Воєнний час після setTime дорівнює 13: 27: 06

Після спроби неправильної установки: Воєнний час: 00; 00: 00 Стандартний час: 12: 00: 00 AM

У нашій програмі конструктор Time просто встановлює початкові значення, рівні 0, даним-елементам, (тобто задає воєнний час, еквівалентний 12AM). Це гарантує, що об'єкт при його створенні перебуває у відомому стані. Неправильні значення не можуть зберігатися в даних-елементах об'єкта типу Time, оскільки конструктор автоматично викликається при створенні об'єкта типу Time, а всі наступні спроби змінити дані-елементи ретельно розглядаються функцією setTime.

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

Функція з тим же ім'ям, що й клас, але з символом-тильда (~) перед нею, називається деструктором цього класу (наш приклад не включає деструктор). Деструктор робить "завершальні службові дії над кожним об'єктом класу перед тим, як пам'ять, відведена під цей об'єкт, буде повторно використана системою.

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

Об’ява класу містить об’яви даних-елементів і функцій-елементів класу. Об’ява функцій-елементів є прототипами функцій. Функції-елементи можуть бути описані всередині класу, але гарний стиль програмування полягає в описі функцій поза визначенням класу.

Відзначимо використання бінарної операції дозволу області дії (::) у кожному визначенні функції-елемента, що випливає за визначенням класу на мал.3. Після того, як клас визначений і його функції-елементи Об’явлені, ці функції-елементи повинні бути описані. Кожна функція-елемент може бути описана прямо в тілі класу (замість включення прототипу функції класу) або після тіла класу. Коли функція-елемент описується після відповідного визначення класу, ім'я функції випереджається ім'ям класу та бінарною операцією дозволу області дії (::). Оскільки різні класи можуть мати елементи з однаковими іменами, операція дозволу області дії "прив'язує" ім'я елемента до імені класу, щоб однозначно ідентифікувати функції-елементи даного класу.

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

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

Цікаво, що функції-елементи printMilitary і printStandard не одержують ніяких аргументів. Це відбувається тому, що функції-елементи неявно знають, що вони друкують дані-елементи певного об'єкта типу Time, для якого вони активізовані. Це робить виклики функцій-елементів більш короткими, ніж відповідні виклики функцій у процедурному програмуванні. Це зменшує також ймовірність передачі неправильних аргументів, неправильних типів аргументів або неправильної кількості аргументів.

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

Часто класи не створюються "на порожнім місці". Звичайно вони є похідними від інших класів, що забезпечують нові класи необхідними їм операціями. Або класи можуть включати об'єкти інших класів як елементи. Таке повторне використання програмного забезпечення значно збільшує продуктивність програміста. Створення нових класів на основі вже існуючих класів називається успадкуванням. Включення класів як елементів інших класів називається композицією.

1.6 Область дії клас і доступ до елементів класу

Дані-елементи класу (змінні, об’явлені у визначенні класу) і функції-елементи (функції, об’явлені у визначенні класу) мають областю дії клас. Функції, що не є елементами класу, мають областю дії файл.

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

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

Але, не можна перевантажити функцію-елемент класу за допомогою функції не з області дії цього класу.

Функції-елементи мають всередині класу область дії функцію: змінні, об’явлені у функції-елементі, відомі тільки цій функції. Якщо функція-елемент об’являє змінну з тим же ім'ям, що й змінна в області дії клас, остання робиться невидимої в області дії функції. Така схована змінна може бути доступна за допомогою операції дозволу області. Невидимі глобальні змінні можуть бути доступні за допомогою унарної операції дозволу області дії.