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

Шаблони класу.

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

Синтаксис

template < опис формального параметра > визначення класу

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

Правила опису шаблонів:

  • Локальні класи не можуть містити шаблони.

  • Шаблони методів не можуть бути віртуальними.

  • Шаблони класу можуть містити статичні елементи.

  • Шаблони можуть бути похідними від інших класів.

Для того, щоб використовувати шаблон:

имя_класса < фактичний параметр > имя_экземпляра_класса

Тип є конкретне представлення деякої концепції (поняття). Наприклад, наявний в С++ тип float з його операци-ями +, - * і так далі забезпечує обмежену, але конкретну версію математичного поняття дійсного числа. Новийтіп створюється для того, щоб дати спеціальне і конкретне визначення поняття, якому ніщо не пряме і очевидно серед вбудованих типів не відповідає. Наприклад, в програмі, яка працює з телефоном, можна було б створити тип trunk_module

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

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

Доступ до об'єктів класу може обмежуватися набором функцій, які описані як частина цього класу. Такі функції називаються функціями членами. Об'єкти класу створюються і ініціалізувалися функціями членами, спеціально для цієї мети описаними. Ці функції називаються конструкторами. Функція член може бути спеціальним чином описана для "очищення" кожного класового об'єкту при його знищенні. Така функція називається деструкцією.

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

Розглянемо реалізацію поняття дати з використанням struct для того, щоб визначити представлення дати date і безліч функцій для роботи із змінними цього типу:

struct date (* int month, day, year; *);

// дата: місяць, день, рік *)

date today;

void set_date(date*, int, int, int);

void next_date(date*);

void print_date(date*);

// ...

Ніякого явного зв'язку між функціями і типом даних не немає. Такий зв'язок можна встановити, описавши функції як члени:

struct date (*

int month, day, year;

void set(int, int, int);

void get(int*, int*, int*);

void next();

void print();

*);

Функції, описані таким чином, називаються функціями членами і можуть викликатися тільки для спеціальної змінної відповідного типу з використанням стандартного синтаксису для доступу до членів структури. Наприклад:

date today; // сьогодні

date my_burthday; // мій день народження

void f()

(*

my_burthday.set(30,12,1950);

today.set(18,1,1985);

my_burthday.print();

today.next();

*)

Оскільки різні структури можуть мати функції члени з однаковими іменами, при визначенні функції члена необхідно указувати ім'я структури:

void date::next()

(*

if ( ++day > 28 ) (*

// робить складну частину роботи

*)

*)

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

Опис date дає безліч функцій для роботи з date, але не указує, що ці функції повинні бути єдиними для доступу до об'єктів типу date. Це обмеження можна накласти використовуючи замість struct class:

class date (*

int month, day, year;

public:

void set(int, int, int);

void get(int*, int*, int*);

void next();

void print();

*);

Влучна public: ділить тіло класу на дві частини. Імена в першій, закритій частині, можуть використовуватися тільки функціями членами. Друга, відкрита частина, складає інтерфейс до об'єкту класу. Struct - це просто class, у якого всі члени класи відкриті, тому функції члени визначаються і використовуються точно так, як і у попередньому випадку. Наприклад:

void date::ptinr()

(*

cout << month << "/" << day << "/" year;

*)

Проте функції не члени відгороджені від використання закритих членів класу date. Наприклад:

void backdate()

(*

today.day--; // помилка

*)

У тому, що доступ до структури даних обмежений явно описаним списком функцій, є декілька переваг. Будь-яка помилка, яка приводить до того, що дата приймає неприпустиме значення (наприклад, Грудень 36, 1985) повинна бути викликана кодом функції члена, тому перша стадія відладки, локалізація, виконується ще до того, як програма буде запущена. Це окремий випадок загального твердження, що будь-яка зміна в поведінці типу date може і повинно викликатися змінами в його членах. Інша перевага - це те, що потенційному користувачеві такого типу потрібно буде тільки дізнатися визначення функцій членів, щоб навчитися їм користуватися.

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

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

class x (*

int m;

public:

int readm() (* return m; *)

*);

x aa;

x bb;

void f()

(*

int а = aa.readm();

int b = bb.readm();

// ...

*)

У першому виклику члена member() m відноситься до aa.m, а в другому - до bb.m.

Покажчик на об'єкт, для якого викликана функція член, є прихованим параметром функції. На цей неявний параметр можна посилатися явно як на this. У кожній функції класу x покажчик this неявно описаний як

x* this;

і ініціалізував так, що він указує на об'єкт, для

якого була викликана функція член. this не може бути описаний

явно, оскільки це ключове слово. Клас x можна еквівалентним

образом описати так:

class x (*

int m;

public:

int readm() (* return this->m; *)

*);

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

Наприклад:

class date (*

// ...

date(int, int, int);

*);

Коли клас має конструктор, всі об'єкти цього класу ініціалізуються. Якщо для конструктора потрібні параметри, вони повинні даватися:

date today = date(23,6,1983);

date xmas(25,12,0); // скорочена форма

// (xmas - різдво)

date my_burthday; // неприпустимо, опущена инициализация\

Часто буває добре забезпечити декілька способів ініціалізації об'єкту класу. Це можна зробити, задавши декілька конструкторів.

Наприклад:

class date (*

int month, day, year;

public:

// ...

date(int, int, int); // день місяць рік

date(char*); // дата в строковому уявленні

date(int); // день, місяць і рік сьогоднішні

date(); // дата за умовчанням: сьогодні

*);

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

date today(4);

date july4("Липень 4, 1983");

date now; // ініціалізувався за умовчанням

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

Для всіх видів контейнерів існують очевидні примеры:таблицы, множини, списки, вектора, словники і так далі Такий клас має операцію "вставити", зазвичай він також має операції для перевірки того, чи був вставлений даний елемент. У нім можуть бути дії для здійснення перевірки всіх елементів в певному порядку, і крім усього іншого, в нім може бути операція для видалення елементу. Зазвичай контейнерні (тобто, що вміщають) класи мають конструктори і деструкції.

Заховання даних і продуманий інтерфейс може дати концепція модуля. Клас, проте, є типом. Щоб використовувати його, необхідно створити об'єкти цього класу, і таких об'єктів можна створювати стільки, скільки потрібно. Модуль же сам є об'єктом. Щоб використовувати його, його треба тільки ініціалізувати, і таких об'єктів рівно один.

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

Індивідуальні завдання:

Загальне завдання

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

  1. Задача «Мікроорганізми». Розробити програму для моделювання життя мікроорганізмів. На прямокутному полі клітинок за законом випадковості в будь-якому напрямі в межах заданого поля стрибають мікроорганізми двох видів. Початкова кількість і вага мікроорганізмів однакова. Якщо мікроорганізм стрибнув на клітинку, яка вже зайнята іншим організмом, то відбувається аналіз ситуації, що складається за правилами, а потім мікроорганізм повертається на своє місце:

    1. якщо в клітинці виявився мікроорганізм того ж самого виду, то вони разом утворюють новий мікроорганізм із заданою початковою вагою;

    2. якщо в клітинці виявився мікроорганізм іншого виду, то їхня вага змінюється за такими правилами:

  1. якщо їхня вага на даний момент однакова, то той мікроорганізм, який стрибнув у клітинку, поглинає половину ваги того мікроорганізму, що її займав, зменшуючи відповідно вдвічі його вагу;

  2. якщо вага мікроорганізмів, що потрапили в одну клітинку, різна, то більший мікроорганізм поглинає половину ваги меншого, зменшуючи його вагу відповідно вдвічі;

    1. мікроорганізм гине у двох випадках:

  1. якщо його вага стала меншою, ніж 10 % від початкової ваги;

  2. якщо його вага стала більшою, ніж 200 % від початкової ваги.

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

В програмі необхідно передбачити можливості:

  1. задавати початкову популяцію мікроорганізмів з файлу;

  2. завдання початкової популяції користувачем в діалоговому режимі, при чому координати клітинок розміщення мікроорганізмів можна задавати за допомогою датчику випадкових чисел чи в ручному режимі;

  3. збереження початкової популяції у файл;

  4. графічне відображення життя популяції на кожному кроці;

  5. завдання кількості кроків життя мікроорганізмів – максимальну кількість популяцій.

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

Перший кидок гравець робить 6 кубиками, другий кидок – 6 - кількість помічених кубиків після першого кидка, третій – 6 - кількість помічених кубиків після першого та другого кидків.

Після останнього кидка гравець повинен обрати один із вільних варіантів та записати його в свою таблицю результатів.

Назва варіанту

Кількість балів

«1»

Кількість кубиків з одиницями

«2»

Кількість кубиків з двійками * 2

«3»

Кількість кубиків з трійками * 3

«4»

Кількість кубиків з четвірками * 4

«5»

Кількість кубиків з п’ятірками * 5

«6»

Кількість кубиків з шестірками * 6

«Повний дім»

Два однакових кубика * Бали + Три однакових кубика * Бали

«5 однакових»

50

«4 однакових»

4 * Бали однакових чотирьох кубиків + Бали п’ятого кубика

«4 різних

25

«5 різних

30

«Сума всіх

Сума балів кубиків

Виграє гравець із максимальною сумою балів.

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

  1. Задача «Життя». У 1970 році математик Д. Конвей запропонував чудовий алгоритм клітинного автомата, який можна вважати грою, що описує популяцію стилізованих організмів, яка розвивається у часу під дією протиборства тенденцій розмноження і вимирання. Дано поле розміром клітинок. На клітинках з фішками є життя, на інших – немає. Сусідами кожної клітинки вважаються всі клітинки, що її очолюють (максимум – 8). Ця система функціонує за такими правилами:

    1. «виживання»: кожна фішка, в якої є дві або три сусідні фішки, виживає і переходить у наступне покоління;

    2. «загибель»: кожна фішка, в якої виявляється більше як три сусіди, гине, тобто зникає з дошки, через перенаселення; кожна фішка, біля якої вільні всі сусідні клітинки або зайнята лише одна, гине через самотність;

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

Процес існування популяції вважається завершеним у трьох випадках:

  1. усі фішки з поля зникли, тобто система вимерла;

  2. на полі немає порожніх клітин, тобто система перенаселена;

  3. на полі не відбувається ніяких змін станів клітин.

Початкове розміщення фішок на полі – довільне.

В програмі необхідно передбачити можливості:

  1. початкове розміщення фішок можна завантажити з файлу чи побудувати вручну;

  2. завдання початкового розміщення фішок користувачем, при чому координати клітинок розміщення фішок можна задавати за допомогою датчику випадкових чисел чи в діалоговому режимі;

  3. збереження початкового розміщення у файл;

  4. графічне відображення життя системи на кожному кроці;

  5. виконувати підрахунок кількості поколінь життя системи.

  1. Гра «Хрестики-ноліки». Розробити програму для гри «Хрестики-ноліки». В гру грають два гравці: один – «Хрестик», другий – «Нолік».На квадратному полі гравці по черзі помічають по одній клітинці: перший гравець позначає хрестиками, другий – ноліками. Виграє той гравець, який побудує лінію зсвоїх позначок (). Лінії можуть бути горизонтальними, вертикальними чи розташовані по діагоналі.

Хрестики та ноліки можна замінити будь-якими іншими картинками, символами тощо.

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

  1. Задача «Сортувальна станція». Написати програму для моделювання процесу формування поїздів на сортувальній станції. На вхід сортувальної станції поступають вагони двох типів. Необхідно сформувати два нові поїзди із вагонів одного типу.

В програмі передбачити такі функції:

    1. завантаження з файлу даних про вагони, з яких слід сформувати поїзди;

    2. користувач може скласти список вагонів в діалоговому режимі та зберегти його у файл;

    3. графічне відображення процесу формування поїздів..

Список вагонів та структуру нових поїздів слід представляти за допомогою динамічної структури даних «Стек».

  1. Задача «Готель». У п’ятизірковому готелі є номерів. Адміністратор має інформацію про кількість місць у кожному номері, перелік зайнятих номерів, кількість вільних місць у кожному номері у них на даний момент, стать клієнтів. Вважається, що разом можуть бути поселені клієнти однієї статі.

У готель прибула група туристів – жінок ічоловіків. Необхідно розселити групу туристів у найменшу кількість номерів за таких додаткових умов:

    1. Група туристів заїхала вночі, тому необхідно враховувати стать клієнтів. Можливе підселення в зайняті номери, але без переселення раніше розташованих клієнтів.

    2. Група туристів заїхала на кілька днів, тому при розселенні враховується стать клієнтів, можливе підселення в зайняті номери та переселення раніше розташованих клієнтів в інші номери.

В програмі передбачити такі функції:

    1. Завантаження з файлу даних про зайнятість номерів готелю.

    2. Збереження у файл даних про зайнятість номерів готелю.

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

    4. Відображення схеми розселення клієнтів по номерам готелю.

  1. Гра «П’ятнашки».Написати програму для гри в п’ятнашки. Ігрове поле складається з п’ятнадцятьох клітинок (4х4). На початку гри на ігровому полі розміщуються п’ятнадцять фішок випадковим чином, які пронумеровані від 1 до 15. Необхідно, переставляючи фішки по ігровому полі, розташувати фішки у такому порядку:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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

В програмі слід передбачити такі можливості:

    1. початкове розміщення фішок на ігровому полі в діалоговому режимі/за допомогою датчику випадкових чисел;

    2. завантаження та збереження ігрового поля в/у файл;

    3. підрахунок кількості перестановок фішок, які зробив гравець, протягом гри;

  1. Гра «Пазли».Розробити програму для гри у пазли. Ця гра є аналогом гри «П’ятнашки», але заміст фішок використовуються фрагменти картинок. Ігрове поле – це задана картинка, яка розбивається на фрагменти, які потім переміщуються. Кількість фрагментів дорівнює , де– кількість рядків та стовпців, на які ділиться картинка.

Задача гравця – розмістити фрагменти в правильному порядку, щоб вони представляли собою початкову картинку.

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

В програмі слід передбачити такі можливості:

    1. завантаження початкової картинки з файлу;

    2. розбивка початкової картинки на фрагментів;

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

    4. початкове розміщення фішок на ігровому полі за допомогою датчику випадкових чисел.

  1. Задача «Предметний вказівник». Розробити програму для формування предметного вказівника. Зберігати інформацію предметного вказівника слід зберігати за допомогою динамічних структур даних. Кожна компонента вказівника містить в собі слово чи словосполучення та номери сторінок книги, де слово зустрічається.

В програмі слід передбачити можливості:

    1. формування предметного вказівника користувачем в діалоговому режимі (функції додавання, вилучення та корегування інформації);

    2. завантаження та збереження предметного вказівника з/у файл;

    3. друкування переліку сторінок, де зустрічається задане слово чи словосполучення;

  1. Задача «Квиток». Використовуючи динамічні структури даних, розробити клас для обробки заявок на залізничні квитки. Кожна заявка включає в себе: номер поїзду, станцію відправлення, станцію призначення, ПІБ пасажира, дата від’їзду, ознака про виконання заявки.

Програма повинна забезпечувати:

    1. зберігання всіх заявок у вигляді списку;

    2. операції додавання, корегування та видалення заявок;

    3. завантаження та збереження списку заявок з/у файл;

    4. друкування всіх заявок;

    5. друкування заявок, які задовольняють умовам відбору: 1) номер поїзду, 2) дата виїзду, 3) пункт відправлення та призначення, 4) № поїзда та дата виїзду.

    6. друкування виконаних заявок;

    7. друкування невиконаних заявок із подальшим їх видаленням.

  1. Задача «Автопарк». Написати програму для ведення обліку роботи автопарку. Використовуючи динамічні структури даних, розробити клас для обліку даних про рух автобусів по маршрутам. Інформація про автобус включає: номер автобуса, ПІБ водія, номер маршруту, ознака місця знаходження автобусу (в парку чи на маршруті).

В програмі передбачити можливості:

    1. формування даних про роботу автобусів (додавання, видалення, корегування даних);

    2. завантаження та збереження даних про автобуси з/у файл;

    3. при виїзді кожного автобуса із парку встановлюється ознака, що автобус на маршруті;

    4. при поверненні автобуса до парку встановлюється ознака «в парку»;

    5. друкування даних про всі автобуси у парку;

    6. друкування даних про всі автобуси на маршруті;

    7. друкування даних про всі автобуси, що рухаються по заданому маршруті тощо.

  1. Задача «Телефонна станція». На міжнародній телефонній станції картотеку абонентів організовано у вигляді динамічного лінійного списку. Кожна розмова характеризується такою інформацією: ПІБ клієнта, ідентифікаційний код, № телефону, адреса, дата розмови, назва країни, до якої дзвонив клієнт, час розмови, ціна за хвилину розмови, ознака оплати розмови.

В програмі передбачити можливості:

    1. формування даних про телефонні розмови (додавання, видалення, корегування даних);

    2. завантаження та збереження даних про телефонні розмови з/у файл;

    3. друкування даних про всі оплачені розмови;

    4. друкування даних про неоплачені розмови;

    5. друкування даних про всі розмови вказаного клієнта тощо.

  1. Задача «Анкета». Анкета опиту населення складається із двох груп запитань. Перша група запитань включає питання про вік, стать та освіту респондента (середня чи вища). Друга група запитань – прямі запитання, на які респондент відповідає «Так» чи «Ні». Використовуючи динамічні лінійні структури даних розробити програму, яка забезпечить виконання таких функцій:

    1. введення анкет в діалоговому режимі;

    2. завантаження та збереження анкет з/у файл;

    3. друкування даних з анкет;

    4. проведення аналізу анкет:

      1. скільки одержано відповідей «Так»чи «Ні» і їхнє процентне співвідношення;

      2. скільки чоловіків/жінок, старших або молодших вказаного користувачем віку, відповіли на запитання «Так»/«Ні»;

      3. скільки чоловіків/жінок, які мають вищу/середню освіту, відповіли на запитання «Так»/«Ні» тощо;

  2. Задача «Словник». Розробити програму для формування англо-українського словника. Для збереження словника можна використовувати динамічні лінійні списки. Кожен компонент списку включає англійське слово чи словосполучення та переклад, а також лічильник звернення до цього слова. Програма повинна забезпечувати виконання таких функцій:

    1. формування словника (додавання, корегування та видалення компонент словника);

    2. завантаження та збереження словника з/у файл;

    3. друкування словника;

    4. друкування даних словника у порядку зростання кількості звертання до слів словника;

    5. пошук необхідного слова чи слово сполучення на англійській/українській мові;

    6. якщо слово, перекладу якого немає у словнику, то слід організувати додавання слова та його перекладу до словника.

  3. Задача «Автостоянка». Автостоянка має лише одну лінію для стоянки машин та один в’їзд. Якщо хазяїн автомобіля приходить забрати своє авто, а воно не являється найближчим до виїзду, то всі автомобілі, які загороджуються виїзд, видаляються зі стоянки, машина виїжджає, потім машини заїжджають на стоянку знову в початковому порядку. Розробити програму для моделювання процесу в’їзду та виїзду автомобілів з автостоянки. При виїзді автомобілю необхідно вказати скільки автомобілів видалялися для цього зі стоянки.

Програма повинна забезпечувати виконання таких функцій:

    1. формування автомобілів на стоянці (додавання, корегування та видалення автомобілів);

    2. завантаження та збереження автомобілів на стоянці з/у файл;

    3. друкування даних про автомобілі на стоянці.