4 - Перегрузка операторов и операторы преобразования типов в C++

Лабораторная работа 4 для студентов курса “Программирование на основе классов и шаблонов” 2 семестра кафедры ИУ5 МГТУ им Н.Э. Баумана.

Содержание

Цель работы

Целью лабораторной работы является изучение механизмов перегрузки операторов и операторов преобразования типов в языке программирования C++, а также формирование практических навыков разработки пользовательских классов, поддерживающих арифметические операции и неявные и явные преобразования типов.

В ходе выполнения лабораторной работы студент осваивает:

Начало работы

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

git pull upstream

или

git pull upstream lab_4

Переключитесь на ветку с текущей лабораторной работой:

git checkout lab_4

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

git push --set-upstream origin lab_4

Задание

Лабораторная работа состоит из двух частей:

Часть 1:

I. Создать класс Fraction для выполнения арифметических операций над обыкновенными дробями.

II. Разработать конструкторы

III. Перегрузить операции потокового ввода дроби с клавиатуры и вывода ее на экран монитора. При вводе и выводе дроби обеспечить автоматическое сокращение дроби и корректный вывод знака.

IV. Создать многофайловый проект и отладить программу, использующую класс Fraction, состоящую из первых пяти логических фрагментов программы (ввод, конструкторы, копирование, операции с дробями, операции с целыми),
приведённой в Приложении 1.

V. Дополнить класс функциями-членами класса и функциями-друзьями класса, которые необходимы для выполнения программы из Приложения 1.

VI. Выполнить программу из Приложения 1 и сравнить результаты с тестовым примером.

предупреждение
Класс Fraction необходимо упаковать в самостоятельную статическую библиотеку.

Часть 2:

  1. Разработать необходимые конструкторы для преобразования простых типов (int, double) к классу Fraction.

  2. Удалить дружественные операторы +, +=, -, -= во всех сочетаниях с простыми типами. Реализовать преобразование типов исключительно с помощью конструкторов и операторов преобразования типов. Все операции сложения реализовать через оператор +=.

Указания по выполнению лабораторной работы

Часть 1.

Создание класса.

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

Числитель и знаменатель дроби имеют тип int.

Дроби вводятся как строка, имеющая вид:

Значения представленных выше дробей на экране при выводе должны иметь вид:

-2 1/3,  8,  6.
3/4,  -3,  -1 1/3.

предупреждение

Создание конструкторов.

Для инициализации объектов разрабатываемого класса обыкновенных дробей предусмотреть соответствующие конструкторы (с одним аргументом типа char* и с двумя аргументами типа int, которые имеют значения по умолчанию).

Перегрузка операций.

Для работы с дробями необходимо:

  1. Перегрузить операции +, += для сложения дробей и дроби_и_целого в любых сочетаниях (дробь+целое, целое+дробь, дробь+дробь).
  2. Перегрузить операции +, += для сложения дроби и double в любых сочетаниях (дробь+double, double+дробь). Преобразование double->дробь должно выполняться с точностью до kNumberDecimalPlaces десятичных знаков после запятой, где kNumberDecimalPlaces - целочисленная константа, задаваемая пользователем. Задайте значение по умолчанию kNumberDecimalPlaces = 4.

осторожно

Для разбора double запрещено использовать тип string.

При перегрузке операций использовать функции-члены класса, а где это невозможно, то функции-друзья класса.

Часть 2.

Вторая часть лабораторной работы необходима для разработки операций преобразований типов. Для этого необходимо создать соответствующие конструкторы или определить методы преобразования типов. При этом удалить дружественные операторы +, +=, -, -= в любых сочетаниях, оставить только базовые методы работы с самим классом (дробь + дробь, += дробь и т д). Сложение определять через +=.

Контрольные вопросы

  1. Как работает перегрузка операторов?

  2. Что значит продолжение жизни временного объекта? Как реализовывается?

  3. Зачем нужны дружественные методы?

  4. Почему в части 2 можно удалить дружественные методы?

  5. В чём отличие конструктора преобразования от оператора преобразования типов?

Приложение 1

#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;
}