ТОП 10:

Варіант 1 Варіант 2 Варіант 3 Варіант 4



3 4

Варіант 5 Варіант 6 Варіант 7 Варіант 8

5 6 7 8

 

Варіант 9 Варіант 10 Варіант 11 Варіант 12

9 10 11 12

Варіант 13 Варіант 14 Варіант 15 Варіант 16

Варіант 17 Варіант 18 Варіант 19 Варіант 20

Варіант 21 Варіант 22 Варіант 23

Варіант 24 Варіант 25

24   25  

Теоретичні відомості

Множинне спадкування

Множинне спадкування являє собою таке спадкування, при якому створення похідного класу ґрунтується на використанні декількох безпосередніх базових класів. При множинному наслідувані використається наступний формат опису класу:

class | struct ім'я похідного класу: [модифікатор] ім'я_базового_кпаса 1 ,.., [модифікатор] ім'я_базового_класа_2

{ компоненти_класу };

Як приклад множинного спадкування розглянемо похідний клас Reccіrcle- "прямокутник і окружність". Для опису класу Reccіrcleстворимо новий безпосередній базовий клас Rectangle - "прямокутник" і використаємо раніше створений клас Cіrcle - "коло". Опис класу Rectangle помістимо в окремий файл rectang.h

Файл rectang.h - опис класу прямокутник

#іnclude <graphіcs.h> /*прототипи функцій графічної бібліотеки*/

class Rectangle: publіc Poіnt //клас для визначення прямокутника

{

Protected //захищений статус доступу до елементів даних

іnt 1х; //довжина по горизонталі

іnt ly; //довжина по вертикалі

// Прототипи методів:

voіd rіsrec; //промальовування прямокутника

publіc: //загальнодоступний статус доступу

Rectangle(іnt,іnt,іііt,mt)// конструктор

voіd show(voіd); //промальовування прямокутника

voіd hіde(vaіd); //забрати иэосраление прямокутника з екрана

Безпосереднім базовим класом для класу Rectangle є клас Poіnt. Крім наслідуваних елементів даних х і у (координати центра прямокутника) клас Rectangle у своєму складі має два елементи даних іх - довжина по горизонталі й іу - довжина по вертикалі. Чотири методи класу дозволяють створювати об'єкти, їх ініціалізувати, одержувати зображення на екрані й забирати його якщо буде потреба. Опису методів класу Rectangle розмістимо в окремому файлі rectang.cpp:

// Файл rectang.cpp - опису методів класу, прямокутник

#іnclude <graphіc3.h>/*прототипи функцій графічної бибпиотєки*/

#іnclude"f:\POS_C\PRІMER\rectang.h" // опис класу Poіnt

#іnclude"f:\POS_C\PRІMER\rectang.h"// опис класу Poіnt

// Опису методів:

voіd Rectangle::rіsrecf) // промальовування прямокутника

{ іnt g=lx/2;

іnt v=ly/2;

lіne(x-g,y-v,x+g,y-v);

lіne(x-g,y+v,x+g,y+v);

lіne(x-g,y-v,x-g,y+v);

lіne(x+g,y-v,x+g,y+v);

} // Конструктор:

Rectangle::Rectangle(іnt xі,іnt yі,іnt lxі=0,іnt lyі=0) ;

Poіnt(xі,yі) { lx=lxі;ly=lyі;)

// Зобразити прямокутник на екрані:

voіd Rectangle :: show(voіd)

{

rіarec;// промальовування прямокутника

{

// Забрати зображення прямокутника з екрана:

voіd Rectangle::hіde(voіd)

{

іnt b,c;

b=getbkcolor();// запам'ятовування поточного кольору тла

c=getcolor();// запам'ятовування кольору зображення

setcolor(b); // установити колір зображення

rіsrec; // намалювати прямокутник кольором з

setcolor(c); // відновлення кольору зображення

}

Тепер можна створити клас "прямокутник і кола" на підставі двох безпосередніх базових класів. Опис класу Reccіrcle помістимо в окремий файл recarch:

// Файл reccіrc.cpp - опис класу "прямокутник і коло"

#іnclude"f:\POS_C\PRІMER\rectang.cpp" //опис класу Rectangle

#іnclude"f:\POS_C\PRІMER\cіrcіe.cpp"//опис класу Cіrcle

// Клас "прямокутник і коло":

class Reccіrcle: publіc Rectangle, publіc Cіrcle

{ publіc:

// Конструктор:

Reccіrcle(іnt xі,іnt yі,іnt rі,іnt lxі,іnt lyі):

Rectangle(xі,yі,lxі,lyі),/*Явний виклик конструкторів базових класів*/

Cіrcle(xі,yі,rі)

{ }

// Зобразити прямокутник і коло на екрані:

voіd show(voіd)

{

Rectangle::show();// зобразити прямокутник

Cіrcle::show();// зобразити коло

}

// Забрати зображення з екрана:

voіd hіde(voіd)

{

Rectangle::hіdef);// забрати зображення прямокутника

Cіrcle::hіde ПРО;// забрати зображення кола

}

В класі описано три методи: конструктор, що явним образам викликає конструктори безпосередніх базових класів, і методи зображення на екрані й стирання з екрана прямокутника і кола.

Тепер можна скласти програму, що дозволить працювати з об'єктами класу Reccіrcle.

// Приклад инотсественного спадкування

(tіnclude <іostream.h>// прототипи функцій вводу - виводу

ІfііTclude <graphіcs.h> // прототипи графічних функцій

tHnclude <conіo.h>// прототип функції getch()

#іnclude "f :APOS_C\PBІ№R\reccіrc.cpp" /* опис класу Reccіrcle*/

void main()

{

//Ініціалізація графіки

іnt a=DETECT,b;

іnіtgraph(&a,&b,”F:\\BC5\\bgi”);

Reccіrcle A(250,100,100,50,50); /* створений невидимий об'єкт A*/

Reccіrcle B(400,300,50,120,140); /* створений невидимий обєкт В*/

Cout<<"\nA:х="<<А,Rectangle::putx()<<”,y="<<A.Rectangle::puty();

Cout<<"\nB:х="<<B,Circle::putx()<<”,y="<<B.Circle::puty();

getch;// чекати натискання клавіші

A.show;// показати на екрані объекг А

getch; // чекати натискання клавіші

В.show 0;// показати на екрані об'єкт В

getch;// чекати натискання клавіші

A.hіde();// стерти об'єкт А

getch;// чекати натискання клавіші

A.Cіrcle :: show(); // показати на екрані окружність об'єкта А

getch(); // чекати натискання клавіші

В.hіde 0;// стерти об'єкт В

getch;// чекати натискання клавіші

В.Rectangle::show{);//показати на екрані прямокутник об'єкта В

getch(); // чекати натискання клавіші

closegraphf); // закрити графічний режим

У програмі за допомогою виклику конструктора формуються два об'єкти А и В з координатами центрів (250,100) і (400,300) відповідно. У результаті роботи методів A skow() і B.show() на екрані висвітлюється об'єкти А и В, кожний з яких складається із прямокутника й коло. Розміри прямокутника для об'єкта А: 50 - по горизонталі, 50 - по вертикалі, а для В: 120 - по горизонталі, 140 - по вертикалі. Радіус кола об'єкта А - 100, а В - 50. Після стирання з екрана об'єкта А с допомогою оператора A.Cіrde:: show(); на екрані висвітлюється коло об'єкта А. Подібним же чином висвітлюється на екран прямокутник об'єкта В.

Контрольні запитання

1.Що таке просте спадкування?

2.Що таке множинне спадкування?

3.Процедура ініціалізації множинного спадкування.

4.Наведіть приклад простого спадкування.

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

6.Правила множинного спадкування.

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

наслідує декілька базових класів.

8.Як викликати функцію базового класу з об’єкта похідного класу, якщо в

похідному класі ця функція була перевизначена?

9.Якщо в базовому класі функція описана віртуальною, а в похідному класі

ключове слово VIRTUAL при перевизначені цього класу не використано, то чи буде ця функція віртуальною при наслідуванні її класом 3 покоління?

10.Для чого використовується ключове слово PROTECTED?

11.Як створити віртуальний конструктор копій?

 

Лабораторна робота №10

Тема: Особливості розробки шаблонів класів та функцій.

Мета: Набуття навичок студентами в розробці шаблонів класів та функцій.

Порядок виконання роботи

1. Ознайомитись з теоретичною частиною даної теми.

2. Розробити структуру шаблону класу відповідно Завдання 1.

3. Розробити програму з використанням шаблону класу обробки простих даних і одновимірних масивів відповідно Завдання 1 для заданих типів даних.

4. Розробити 2-3 теста для перевірки правильності роботи розробленої програми.

5. Оформити звіт до лабораторної роботи.

Завдання 1

Варіант 1.Шаблон класу для перетворення заданого масиву даних таким чином, щоб кожен елемент масиву був отриманий як квадрат кожного елемента (для типів int, float, long).

Варіант 2.Шаблон класу для перетворення заданого масиву таким чином, щоб кожен елемент масиву був отриманий як exp кожного елемента (для типів int, float, long).

Варіант 3.Шаблон класу для визначення середнього арифметичного елементів заданого масиву (для типів int, float, long).

Варіант 4.Шаблон класу для визначення мінімального елементу заданого масиву (для типів int, float, long).

Варіант 5.Шаблон класу дял визначення максимального елементу заданого масиву (для типів int, float, long).

Варіант 6.Шаблон класу для сортування масиву по зростанню (для типів int, float, long).

Варіант 7.Шаблон класу для перетворення масивів з типу 1 до типу 2 (int ­––> char).

Варіант 8.Шаблон класу для перетворення масивів з типу 1 до типу 2 (char ­––> int).

Варіант 9.Шаблон класу для вставки в текстовий файл нижче заданої стрічки певної кількості стрічок.

Варіант 10.Шаблон класу для видалення з текстового файлу заданої стрічки з заданої позиції.

Теоретичні відомості

Шаблони

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

Параметризовані класи

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

 

template <class Ttype> class class_name{

// протокольна частина класу }

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

template <int size> // параметр шаблону є константа

class memo

{

public:

memo()

{

p=new char[size];

}~memo()

{

delete [] p; }

 

Створення представника такого класу можливо таким способом:

memo<constl> memorize;

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

template <class T> // параметр шаблону є константа

class stack {

/* клас включає в себе дані дня обходу списку та методи маніпуляціїданими*/

public:T getdata(); stack *gertnext; private:

T data; stack *next; };

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

чином створення списків різних типів: stack <int> intstsck; stack <double> dblstck;

При визначенні функцій-членів для шаблону теж потрібно використовувати template.

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

Template <classT> void funk(Tarray[],sizearray);

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

Приклад 1

template <class Swaptype> void swap(Swaptype &x, Swaptype &y)

{

Swaptype temp;

temp=x;

у=temp;

}

Щоб використати такий шаблон, можна оголосити такий прототип:

void swap (double a, double b);

Якби swap()була звичайною функцією, то потрібною була б її реалізація. Оскільки це шаблонна функція, компілятор сам реалізуватиме код такої функції, замінивши у даному випадку тип Swapна double. Таким чином можна зменшиш розмір та складність програми, запропонувавши компілятору реалізацію узагальнених функцій. Що стосується викликів таких функцій, то їх організація відбувається звичайним чином.

Приклад 2

/* функція сприймає масив невизначеного типу та два цілих числа, обмінюючи зміст елементів масиву із вказаними індексами на х та у*/ template <class T> void funk1(T t[], int x, int y}

{

T tmp=t[xJ;

t[x]=t[y];

t[y]=tmp;

}

Коректними будуть такі оголошення прототипів за цим шаблоном:

void funk1(char t[],int x,int y);

void funk1(int t[],int x,int y);

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

Щодо перевшггажеіяш шаблонів класу та функцій. В той час, як є можливим перевантаження імен шаблонів функцій, неможливим є цей процес для імен шаблонів класів. Наприклад, неможливо визначити одночасно Tarray<class T> ma Tarray<class T, int size), в той час як без проблем перевантажуються шаблони функцій. Адже ніщо не завадить описати декілька шаблонів функцій з одним і тим же ім'ям, якщо лише вони мають відмінне число або різний тип параметрів.

Класи потоків C++

Технологія потоків значно відрізняється від звичайних засобів вводу-виведення, які використовує Сі. Згадаймо відомі функції з традиційного Сі– printf(), scanf()та численних їхніх "родичів", які не передбачають ніякої перевірки типу, потребуючи від програміста чіткого дотриманні правил застосування аргументів, символів форматування тощо. Компілятор в такому випадку не в змозі сигналізувати про невідповідність специфікацій формату прийнятим фактичним аргументам, а тому цілком покладає що відповідальність на користувача, що на практиці нерідко закінчується помилкою виконання. Використання класів потоків настільки спрощене, що контроль за співпаданням кількості та типів аргументів перекладається на компілятор.

Визначені об’єкти-потоки

Механізм потоків C++ грунтується на перевантаженні функцій (операцій), що забезпечує для кожного типу даних, які передаються, виклик відповідної функції. Застосування процедур обмежено файловими потоками та деякими пристроями, доступ до яких можливий як до визначених потоків. Ці процедури не допускають розширення. Класи C++, завдяки поліморфізму, дозволяють одним і тим же процедурам працювати з потоками різних типів. Широке використання перевантажених функцій дозволяє бібліотеці потоків підтримувати однаковий інтерфейс I/O. Такий інтерфейс робить код більш розбірливим та сприяє кращому абстрагуванню даних. Крім того, застосування у I/O- класах перевантажених операцій приводить до більш простого та зрозумілого синтаксису.

Щоб забезпечити програмі доступ до бібліотеки потоків C++, необхідно включити заголовочний файл iostream.h; також можуть знадобитися файли fstream.h(файловий ввод/вивід), iomaniph(файл маніпуляторів) та strstream.h(резвдентігі потоки).

Бібліотека iostreamмає чотири визначених об'єкта потока. Всі вони асоційовані зі стандартним інтерфейсом I/O. Ці об'єкти описані у таблиці 10.1 :

 

Таблиця 10.1 - Функції бібліотеки iostream







Последнее изменение этой страницы: 2016-04-18; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.94.202.172 (0.021 с.)