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

МІНІСТЕРСТВО ОСВІТИ І НАУКИ, МОЛОДІ ТА СПОРТУ УКРАЇНИ

НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ ЛЬВІВСЬКА ПОЛІТЕХНІКА

ОБ’ЄКТНО-ОРІЄНТОВАНЕ ПРОГРАМУВАННЯ

МЕТОДИЧНІ ВКАЗІВКИ

до виконання лабораторної роботи

на тему:

“Класи”

для студентів базового напряму 6.050101 “Комп’ютерні науки”

Затверджено

на засіданні кафедри загальної екології

та екоінформаційних систем

Протокол № 13 від 24.05.2012 р.

Львів – 2012

Об’єктно-орієнтоване програмування: Методичні вказівки до виконання лабораторної роботи на тему “Класи” для студентів базового напряму 6.050101 “Комп’ютерні науки” / Укл.: І. Я. Казимира, О. Н. Кузь. – Львів: Видавництво Національного університету “Львівська політехніка”, 2012. – 23с.

Укладачі: Казимира І. Я., к.т.н., доц.

Кузь О. Н., асист.

Відповідальний за випуск: Заяць В. М., д.т.н., проф.

Рецензенти: Яцимірський М. М., д.т.н., проф.,

Фармага І. В., к.т.н., доц.

Вимоги до виконання лабораторної роботи

Кожен студент отримує індивідуальне завдання на лабораторну роботу (варіанти завдань відповідають номеру студента у журналі академічної групи).

Звіт про виконання індивідуального завдання лабораторної роботи обов’язково повинен містити такі пункти:

  1. Титульна сторінка встановленого зразка

  2. Формулювання завдання відповідного варіанту

  3. Опис розробки (опис класів відповідно до завдання, пояснення розроблених конструкторів, деструкторів, інших методів, відношень між класами, способів перевантаження операцій, тощо).

  4. Текст програми (з обов’язковими коментарями, що пояснюють хід виконання завдання).

  5. Протокол виконання програми

  6. Висновки

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

ЗРАЗОК ТИТУЛЬНОЇ СТОРІНКИ

МІНІСТЕРСТВО ОСВІТИ І НАУКИ, МОЛОДІ ТА СПОРТУ УКРАЇНИ

НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”

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

Кафедра загальної екології та

екоінформаційних систем

Лабораторна робота

з дисципліни Об’єктно-орієнтоване програмування

на тему:

Класи

Варіант 1

Виконав:

студент групи КН-28

Петренко А.А.

Перевірив:

ас. Кузь О.Н.

Львів – 2012

Класи

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

Поняття класу є, напевно, найбільш важливим у мові С++. Синтаксис опису класу схожий на синтаксис опису структури. Це його основна форма:

class <ім’я_класу>

{

//закриті функції-члени і дані-члени класу

public:

//відкриті функції-члени і дані-члени класу

} <список_об’єктів>;

В описі класу <список_об’єктів> не є обов’язковим. Ви можете оголосити об’єкти класу пізніше, по мірі необхідності. Так переважно і роблять. Хоча <ім’я_класу> також є не обов’язковим, проте його зазвичай вказують. <ім’я_класу> стає новим іменем типу даних, яке використовується для виявлення об’єктів цього класу.

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

Приклад оголошення класу:

class AnyClass

{

//закриті елементи класу

іnt a;

public:

int get_a();

void set_a(int num);

};

Хоча функції get_a() і set_a() і оголошені в класі AnyClass, вони ще не визначені. Для визначення функцій-члена потрібно пов’язати ім’я класу, частиною якого виявляється функція-член, з ім’ям функції. Це досягається шляхом написання імені функції відразу після імені класу з двома двокрапками. Операцію, яку записують у вигляді двох двокрапок, називають операцією розширення області видимості. Для задання функції-члена використовується наступна загальна форма:

<Тип> <ім’я_класу>::<ім’я_функції>

(<список_параметрів>)

{

//тіло функції

}

Нижче наведені приклади визначення функцій-членів get_a() і set_a():

void AnyClass::get_a()

{

return a;

}

int AnyClass::set_a(int num)

{

a = num;

}

Оголошення класу AnyClass не приводить до створення об’єктів типу AnyClass. Щоб створити об’єкт відповідного класу, потрібно просто використати ім’я класу як специфікатор типу даних. Наприклад:

AnyClass ob1, ob2;

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

Наприклад:

ob1.set_a(10);

ob2.set_a(37);

Ці оператори встановлюють значення змінної а в об’єктах ob1 і ob2. Кожен об’єкт містить власну копію всіх даних, які оголошені в класі. Це означає, що значення змінної а в ob1 відмінне від значення цієї змінної в ob2.

Доступ до елементів даних класу можна отримати і з допомогою вказівника на об’єкт цього класу. Наступний приклад це показує.

class Coord

{

public:

int x,y;

void SetCoord(int_x, int_y);

};

void

Coord::SetCoord(int_x, int_y)

{

x = _x;

y = _y;

}

int main()

{

Coord pt;

Coord *ptPtr = &pt; //вказівник на об’єкт

//...

pt.x = 0;//обєкт.член_класу

ptPtr->y = 0;//вказівник->член_класу

ptPtr->SetCoord(10,20);

//...

return 0;

}

Серед програмістів часто виникає дискусія про те, який метод доступу до членів класу – через оператор "." чи через оператор "->" – працює швидше. Розглянемо це питання. Оператор вибору члена “.” працює так само, як і оператор “->”, проте відмінність полягає в тому, що перед ім’ям об’єкту є неявно згенерований компілятором оператор адреси “&”. Таким чином, інструкцію

ObjName.FuncName();

компілятор трактує, як

(&ObjName)->FuncName();

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

<ім’я_класу>::<ім’я_члена>

Мова С++ накладає певні обмеження на дані-члени класу:

  • дані-члени не можуть визначатись з модифікаторами auto, extren чи register;

  • даним-членам класу не може бути об’єкт цього ж класу (проте даним-членом може бути вказівник або посилання на об’єкт цього класу, чи сам об’єкт іншого класу).

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

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

class <ім’я_класу>;

Розглянемо наступний приклад.

//Неповне оголошення класу

class PrevDecl;

class AnyClass

{

int x;

PrevDecl* obPtr;

public:

Any Class(int_x){x = _x;}

};

int main()

{

//тіло основного блоку

return 0;

}

//Повне оголошення класу

class PrevDecl

{

int a;

public:

PrevDecl();

};

Не можна створити об’єкт не повністю визначеного класу. Спроба створення такого класу приведе до помилки компіляції.

Зауважимо, що визначення класу нагадує визначення структури, за винятком того, що визначення класу:

  • зазвичай містить один або декілька специфікаторів доступу, які задаються за допомогою ключових слів public, protected чи private;

  • замість ключового слова struct можуть використовуватись class чи union;

  • зазвичай містить поряд з елементами даних фунції-члени;

  • зазвичай містить деякі спеціальні функції-члени, такі як конструктор і деструктор.

Нижче наведені приклади визначення класів з використанням ключових слів struct i union.

struct Point

{

private:

int x;

int y;

public:

int GetX();

int GetY();

void SetX(int_x);

void SetY(int_y);

};

union Bits

{

Bits(unsigned int n);

void ShowBits();

unsigned int num;

unsigned char c[sizeof(unsigned int)];

};

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

Таблиця 1

Специфікатори доступу до класу

Специфікатор

Опис

private:

Дані-члени і функції-члени доступні тільки для функцій-членів цього класу

protected:

Дані-члени і функції-члени доступні для функцій-членів даного класу і класів, які є похідними від нього

public:

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

В С++ клас, структура і об’єднання розглядаються як типи класів. Структура і клас схожі один на одного, за винятком доступу по замовчуванню: в структурі елементи мають по замовчуванню доступ public, а клас private. Об’єднання, як і структура, по замовчуванню має доступ public.

В наведеній нижче таблиці 2 наведені ці відмінності.

Таблиця 2

Відмінності між класом, структурою та об’єднанням

Відмінності

Класи

Структури

Об’єднання

Ключове слово:

class

struct

union

Доступ по замовчуванню:

private

public

public

Перекриття даних:

ні

ні

так

Структури і об’єднання можуть мати конструктори і деструктори. Поряд з цим є декілька обмежень на використання об’єднань в якості класів. По-перше, вони не можуть успадковувати будь-який клас, і вони самі не можуть використовуватись в якості базового класу для будь-якого іншого типу. Загалом, об’єднання не підтримують ієрархію класів. Об’єднання не можуть мати членів с атрибутом static. Вони також не повинні містити об’єктів з конструктором і деструктором.

Розглянемо приклад використання об’єднання в якості класу:

#include <iostream.h>

union Bits

{

Bits(unsigned int n);

void ShowBits();

unsigned int num;

unsigned char c[sizeof(unsigned int)];

};

Bits::Bits(unsigned int n)

{

num = n;

}

void

Bits::ShowBits()

{

int i, j;

for (j=sizeof(unsigned int)-1; j>=0; j--)

{

cout<<”Двійкове подання байта”<<j<< ”:”;

for (i=128; i; i>>=1)

{

if (i & c[j]) cout <<”1”;

else cout <<”0”;

}

cout<<”\n”;

}

}

int main()

{

Bits ob(2000);

ob.ShowBits();

return 0;

}

В цьому прикладі здійснюється побайтовий вивід переданого об’єкту беззнакового цілочисельного значення у двійковому вигляді.

Конструктори і деструктори Список ініціалізації елементів

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

#include <iostream.h>

class AnyClass

{

int var;

public:

AnyClass();//Коструктор

void Show();

};

AnyClass:: AnyClass()

{

cout<<”В конструкторі\n”;

var=0;

}

void

AnyClass::Show()

{

cout<<var;

}

int main()

{

AnyClass ob;

ob.Show();

return0;

}

В цьому прикладі конструктор класу AnyClass виводить повідомлення на екран та ініціалізує значення закритої змінної класу var.

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

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

Функція-член, яка виконує дії, зворотні конструктору, називається деструктором. Ця функція-член викликається при видаленні об’єкта. Деструктор зазвичай виконує роботу по звільненні пам’яті, яка є зайнята об’єктом. Він має те ж саме ім’я, що і клас, якому він належить, з попереднім символом “~” і не має значення, яке повертається.

Розглянемо приклад класу, який містить в собі деструктор:

#include<iostream.h>

class AnyClass

{

int var;

public:

AnyClass(); //Конструктор

~AnyClass(); //Деструктор

void Show();

};

AnyClass:: AnyClass()

{

cout<<”Ми в конструкторі\n”;

var=0;

}

AnyClass::~ AnyClass()

{

cout<<”Ми в деструкторі\n”;

}

void

AnyClass::Show()

{

cout<<var<<”\n”;

}

int main()

{

AnyClass ob;

ob.Show();

return 0;

}

Деструктор класу викликається в момент видалення об’єкта. Це означає, що для глобальних об’єктів він викликається при завершенні програми, а для локальних — коли вони виходять з області видимості. Зауважимо, що неможливо отримати вказівники на конструктор і деструктор.

Зазвичай конструктор містить параметри, які дозволяють при побудові об’єкту задати йому деякі аргументи. В переглянутому вище прикладі конструктор ініціалізував закриту змінну var класу AnyClass значенням 0. Якщо потрібно проініціалізувати змінні класу, використовується конструктор з параметрами. Модифікуємо попередній приклад:

#include<iostream.h>

class AnyClass

{

int a, b;

public:

//Конструктор з параметрами

AnyClass(int x, int y);

//Деструктор

~AnyClass();void Show();

};

AnyClass:: AnyClass(int x, int y)

{

cout<<”Ми в конструкторі\n”;

a = x;

b = y;

}

AnyClass::~AnyClass()

{

cout<<”Ми в деструкторі\n”;

}

void

AnyClass::Show()

{

cout<<a<<” ”<<b<<”\n”;

}

int main()

{

AnyClass ob(3,7);

ob.Show();

return 0;

}

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

Фактично, синтаксис передачі аргументу конструктору з параметрами є скороченою формою запису наступного виразу:

AnyClass ob = Any Class(3,7);

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

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

Наведемо правила, які існують для конструкторів:

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

  • конструктор не може передавати значення;

  • конструктор не успадковується;

  • конструктор не може бути оголошений з модифікатором const, volatile, static, virtual.

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

Для деструкторів існують наступні правила:

  • деструктор не може мати параметрів;

  • деструктор не може повертати значення;

  • деструктор не успадковується;

  • клас не може мати більше одного деструктора;

  • деструктор не може бути оголошений з модифікатором const, volatile, static, virtual;

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

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

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

Class AnyClass()

{

int a, b;

public:

anyClass(int x, int y)

};

//Конструктор використовує список ініціалізації

AnyClass::AnyClass(int x, int y): a(x), b(y)

{

}

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]