Лабораторная работа 4 для студентов курса “Программирование на основе классов и шаблонов” 2 семестра кафедры ИУ5 МГТУ им Н.Э. Баумана.
Целью лабораторной работы является изучение механизмов перегрузки операторов и операторов преобразования типов в языке программирования C++, а также формирование практических навыков разработки пользовательских классов, поддерживающих арифметические операции и неявные и явные преобразования типов.
В ходе выполнения лабораторной работы студент осваивает:
Зайдите в свою локальную директорию с репозиторием для выполнения лабораторных работ. Заберите ветку с соответствующей лабораторной работой из общего репозитория:
git pull upstream
или
git pull upstream lab_4
Переключитесь на ветку с текущей лабораторной работой:
git checkout lab_4
Свяжите ветку локального репозитория с вашим удаленным репозиторием:
git push --set-upstream origin lab_4
Лабораторная работа состоит из двух независимых заданий:
I. Создать класс Fraction для выполнения арифметических операций над обыкновенными дробями.
II. Разработать конструкторы
III. Перегрузить операции потокового ввода дроби с клавиатуры и вывода ее на экран монитора. При вводе и выводе дроби обеспечить автоматическое сокращение дроби и корректный вывод знака.
IV. Создать многофайловый проект и отладить программу, использующую класс Fraction, состоящую из первых пяти логических фрагментов программы (ввод, конструкторы, копирование, операции с дробями, операции с целыми),
приведённой в Приложении 1.
V. Дополнить класс функциями-членами класса и функциями-друзьями класса, которые необходимы для выполнения программы из Приложения 1.
VI. Выполнить программу из Приложения 1 и сравнить результаты с тестовым примером.
предупреждение
КлассFractionнеобходимо упаковать в самостоятельную статическую библиотеку.
Целью является демонстрация альтернативного подхода к перегрузке операторов без использования дружественных функций.
Необходимо:
Разработать необходимые конструкторы для преобразования простых типов (int, double) к классу Fraction.
Реализовать альтернативный вариант класса Fraction, в котором:
Программа из Приложения 1 должна корректно работать в обоих вариантах реализации класса, несмотря на различие механизмов перегрузки.
Часть 1.
Создание класса.
В данной лабораторной работе необходимо создать класс для работы с обыкновенными дробями. Все операции, которые должны выполняться с дробями, включены в программу в Приложении 1.
Числитель и знаменатель дроби имеют тип int.
Дроби вводятся как строка, имеющая вид:
-2 6/18, 5 9/3, 2 4/1.3/4, -9/3, -8/6 (знаменатель всегда положительный).-2, 0, 4.-5 88/2.Значения представленных выше дробей на экране при выводе должны иметь вид:
-2 1/3, 8, 6.
3/4, -3, -1 1/3.
предупреждение
- Предусмотреть генерацию исключения или сообщение об ошибке при обработке некорректных данных:
4/0,-1 3/0.- При выводе и после выполнения арифметических операций дроби сокращаются, то есть числитель и знаменатель не должны иметь общих множителей.
Создание конструкторов.
Для инициализации объектов разрабатываемого класса обыкновенных дробей предусмотреть соответствующие конструкторы (с одним аргументом типа char* и с двумя аргументами типа int, которые имеют значения по умолчанию).
Перегрузка операций.
Для работы с дробями необходимо:
осторожно
Для разбора double запрещено использовать тип
string.
При перегрузке операций использовать функции-члены класса, а где это невозможно, то функции-друзья класса.
Обратите внимание: операция вида
int + Fractionне может быть реализована как метод класса.
Часть 2.
Вторая часть лабораторной работы необходима для разработки операций преобразований типов.
Для этого необходимо создать соответствующие конструкторы или определить методы преобразования типов. Для выполнения Части 2 необходимо реализовать вторую версию класса Fraction (в отдельном проекте или модуле), в которой:
оператор +=.Контрольные вопросы
Как работает перегрузка операторов?
Что значит продолжение жизни временного объекта? Как реализовывается?
Зачем нужны дружественные методы?
Почему в части 2 можно удалить дружественные методы?
В чём отличие конструктора преобразования от оператора преобразования типов?
#include <iostream>
#include "fraction.h"
int main() {
Fraction z;
std::cout << "Введите дробь: ";
std::cin >> z;
std::cout << "1. Ввод дроби с клавиатуры\n";
std::cout << "z = " << z << std::endl;
Fraction fr1(10, 14);
Fraction fr2;
Fraction fr3("-1 4/8");
std::cout << "2. Проверка конструкторов\n";
std::cout << "fr1 = " << fr1 << std::endl;
std::cout << "fr2 = " << fr2 << std::endl;
std::cout << "fr3 = " << fr3 << std::endl;
Fraction x(z);
std::cout << "3. Проверка копирующего конструктора\n";
std::cout << "x = " << x << std::endl;
std::cout << "4. Арифметические операции (дробь + дробь)" << std::endl;
Fraction y = x + fr1;
std::cout << "y = x + fr1 = " << y << std::endl;
y += fr3;
std::cout << "y += fr3 -> " << y << std::endl;
std::cout << "5. Арифметика с целыми числами" << std::endl;
int i = 5;
y = x + i;
std::cout << "y = x + i = " << y << std::endl;
y = i + x;
std::cout << "y = i + x = " << y << std::endl;
y += i;
std::cout << "y += i -> " << y << std::endl;
std::cout << "6. Арифметика с double" << std::endl;
double d = -1.25;
Fraction f = d; // Преобразование double -> Fraction (используется в части 2)
std::cout << "f = " << f << std::endl;
y = x + d;
std::cout << "y = x + d = " << y << std::endl;
y = d + x;
std::cout << "y = d + x = " << y << std::endl;
y += d;
std::cout << "y += d -> " << y << std::endl;
y += d + i;
std::cout << "y += d + i -> " << y << std::endl;
return 0;
}