Lab 4 Prog Done

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 10

Міністерство Освіти і Науки України

Київський Національний Університет імені Тараса Шевченка

Факультет Інформаційних Технологій

Звіт з лабораторної роботи №4


з дисципліни Технології програмування

Вико
нав студент групи ІР-22
Музика Марк Сергійович
Викладач : к.ф.-м.н., ас. Пономарнеко Роман
Миколайович

Київ – 2021
ЗМІСТ
1. Постановка завдання 3
2. Аналітичні викладки 3
3. UML діаграма класу 4
4. Код програми 5
5. Тестування програми 10
6. Висновок 10
Лабораторна робота №4
Тема: Операторні та дружні функції С++.
Мета: вивчити особливості операторних та дружніх функцій. Освоїти
принципи написання: функцій перетворення типів об'єктів,
перевантаження операцій та дружніх функцій.
Етапи виконання завдання:
Розробити покроковий алгоритм вирішення розрахункової частини завдання
і підзадач (при необхідності). Розробити UML діаграму класів. Виконати
програмну реалізацію завдання відповідно до варіанту. Прототипи класів
повинні містяться в окремому * .h- файлі. У програмі обов'язково передбачити
висновок інформації про виконавця роботи (ПІБ), номер варіанта, обраному
рівні складності і завданні. Передбачити можливість повторного запуску
програми (запит про бажання вийти з програми, або продовжити роботу).
Ключові моменти програми обов'язково повинні містити коментарі.
Завдання 1

Аналітичні викладки:
Операторні функції застосовуються для задання нових правил виконання
стандартних операцій для об'єктів. Часто виникає необхідність виклику
класової функції з іншої функції цього ж класу. Функції визначають дії над
одним і тим же об'єктом, в цьому випадку вкладений виклик функції
розуміється як передача повідомлень об'єкта самому собі. Покажчик, що
визначає об'єкт, для якого викликана вкладена функція-елемент, має ім'я
this. Будь-яка функція-елемент завжди в якості першого параметра має
неявний параметр, покажчик на об'єкт, для якого визначена функція:
constклас *this. Функції перетворення не мають аргументів, не вказується тип
значення, що повертається, хоча return обов'язковий, не може бути
віртуальною, не успадковується.
Всі операції в С ++ можуть бути перевантажені, крім операцій точка (.), роз
іменування (*), дозвіл області дії (:), умовна (? :) та sizeof. Операції =, [], () і->
можуть бути перевантажені тільки як нестатичні функції-елементи, не
можуть бути перевантажені для перелічуваних типів. Всі інші операції можна
перевантажувати, щоб застосовувати їх до якихось нових типів об'єктів, які
вводяться користувачем. Операції перевантажуються шляхом опису та
визначення функції, як це робиться для будь-яких функцій, за винятком того,
що в цьому випадку ім'я функції складається з ключового слова operator.
Перевантаження не може змінювати пріоритет та асоціативність операцій, а
також не можна змінити число операндів операції. Перевантажені функції не
успадковуються. Бінарні операції перевантажуються функцією з одним
параметром, покажчиком на інший аргумент є this. Унарні операції
перевантажуються функцією без параметрів.
У деяких випадках бажано забезпечити доступ до закритих елементів
(наділити властивістю 1) функції, які не є елементами даного класу. Це можна
зробити, оголосивши відповідну функцію як одного класу за допомогою
специфікатор friend. Іноді можна бачити, що перевантажена операція також
описується, як дружня, але, зазвичай, дружні функції використовуються рідко.
Їх присутність в програмі зазвичай означає те, що ієрархія класів потребує
видозмінення. Дружність функцій та класів слід використовувати тільки в
тому випадку, коли це дійсно необхідно, наприклад, коли без цього
довелося б використовувати надто складну ієрархію класів.
UML діаграма класів:
Код програми:
Lab4.cpp:

#include "pch.h"
#include "Fraction.h"
#include <iostream>
#include <string>
#include <ctime>

using namespace std;

void print_out(Fraction* fraction, char k)


{
int M, N;
char flag;

switch (k) {
case '+': cout << "Бажаєте додати число чи об'єкт типу Fraction: введiть n або f
вiдповiдно" << endl;
break;
case '-': cout << "Бажаєте вiдняти число чи об'єкт типу Fraction: введiть n або f
вiдповiдно" << endl;
break;
case '*': cout << "Бажаєте помножити на число чи на об'єкт типу Fraction: введiть n
або f вiдповiдно" << endl;
break;
case '/': cout << "Бажаєте подiлити на число чи на об'єкт типу Fraction: введiть n
або f вiдповiдно" << endl;
break;
}
cin >> flag;

if (flag == 'n')
{
cout << "Введiть число: ";
cin >> M;

switch (k) {
case '+': fraction = *fraction + M;
break;
case '-': fraction = *fraction - M;
break;
case '*': fraction = *fraction * M;
break;
case '/': fraction = *fraction / M;
break;
}
fraction->print();
}
else
{
cout << "Введiть чисельник: ";
cin >> M;

cout << "Введiть знаменник: ";


cin >> N;
Fraction* fraction_temp = new Fraction(M, N);

switch (k) {
case '+': fraction = *fraction + fraction_temp;
break;
case '-': fraction = *fraction - fraction_temp;
break;
case '*': fraction = *fraction * fraction_temp;
break;
case '/': fraction = *fraction / fraction_temp;
break;
}
fraction->print();
}
}

int main()
{
setlocale(0, "rus");

cout << "Варiант 11(Б)" << endl;


cout << "Музика Марк IP-22" << endl;

char p = 'y';
int N, M;
int temp_x, temp_y;

while (p == 'y')
{
cout << "Введiть чисельник: ";
cin >> M;

cout << "Введiть знаменник: ";


cin >> N;

Fraction* fraction = new Fraction(M, N);


cout << "Введений дрiб:" << endl;
fraction->print();

Fraction** fraction_array = new Fraction*[4];

for (int i = 0; i < 4; i++)


fraction_array[i] = fraction;

print_out(fraction_array[0], '+');
print_out(fraction_array[1], '-');
print_out(fraction_array[2], '*');
print_out(fraction_array[3], '/');

cout << "Бажаєте продовжити використання, якщо так то введiть y, якщо нi то n:


";
cin >> p;

while ((p != 'y') && (p != 'n'))


{
cout << "Повторiть спробу: ";
cin >> p;
}
}

return 0;
}

Fraction.h:

#pragma once

class Fraction {
private:
int up; //in instruction it is m
int down; //in instruction it is n

int gcd(int M, int N); //greatest common divisor of fraction up and down
public:
Fraction(void);
Fraction(int M, int N);
Fraction* operator +(int X);
Fraction* operator +(Fraction* X);

Fraction* operator -(int X);


Fraction* operator -(Fraction* X);

Fraction* operator *(int X);


Fraction* operator *(Fraction* X);

Fraction* operator /(int X);


Fraction* operator /(Fraction* X);

void print(void) const;


};

Fraction.cpp:

#include "pch.h"
#include "Fraction.h"
#include <iostream>

using namespace std;

Fraction::Fraction(void) : up(0), down(1)


{
}

Fraction::Fraction(int M, int N) : up(M), down(N)


{
int temp_gcd = gcd(up, down);
if (temp_gcd != 0)
{
up = up / temp_gcd;
down = down / temp_gcd;
}
else
{
up = 1;
down = 1;
}
}

Fraction* Fraction::operator+(int X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = temp->up + (temp->down * X);

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction* Fraction::operator+(Fraction* X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = (temp->up * X->down) + (X->up * temp->down);
temp->down = temp->down * X->down;
int temp_gcd = gcd(temp->up, temp->down);
if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator-(int X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = temp->up - (temp->down * X);

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator-(Fraction* X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = (temp->up * X->down) - (X->up * temp->down);
temp->down = temp->down * X->down;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator*(int X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = temp->up * X;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator*(Fraction* X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = temp->up * X->up;
temp->down = temp->down * X->down;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator/(int X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->down = temp->down * X;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}

return temp;
}

Fraction * Fraction::operator/(Fraction* X)
{
Fraction* temp = new Fraction(this->up, this->down);
temp->up = temp->up * X->down;
temp->down = temp->down * X->up;

int temp_gcd = gcd(temp->up, temp->down);


if (temp_gcd != 0)
{
temp->up = temp->up / temp_gcd;
temp->down = temp->down / temp_gcd;
}
else
{
temp->up = 1;
temp->down = 1;
}
return temp;
}

int Fraction::gcd(int M, int N) {


if (N == 0)
return M;
else
return gcd(N, M % N);
}

void Fraction::print(void) const


{
cout << up << endl;
cout << "------" << endl;
cout << down << endl;
}

Тестування програми:

Висновок: Я вивчив особливості операторних та дружніх функцій. Освоїв


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

You might also like