
2 семестр ФИБС / Информатика / ИДЗ Беляев / идз4
.docxМИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра информационно измерительных систем и технологий
отчет
по индивидуальному домашнему заданию №4
по дисциплине «Информатика»
Тема: Перегрузка операторов в C++
Студент гр. |
|
|
Преподаватель |
|
Беляев Ф.Я. |
Санкт-Петербург
2020
ОГЛАВЛЕНИЕ
Цель 3
Задачи 3
Ход работы 5
Вывод 12
ПРИЛОЖЕНИЕ 13
Цель
Создать класса RaceFinal, описывающий результат заезда машин в гонке. Перегрузить операторы класса Car.
Задачи
1. Для решения задачи структуру Car следует преобразовать в класс и дополнить его функционал.
1.1. Предусмотреть конструктор по умолчанию, дабы ранее написанный функционал мог работать.
1.2. Создать конструктор копирования для класса Car. Он потребуется для работы операторов.
1.3. Предусмотреть логический признак машины, выбывшей из гонки.
1.4. Предусмотреть целочисленное значения количество пройденных машиной кругов.
2. Дополнить класс Car операторами:
2.1. Создать бинарный оператор суммирования «+» экземпляров классов Car, результатом должен быть экземпляр содержащий сумму времени обоих операндов.
2.2. Создать бинарный оператор разности «-« экземпляров классов Car, результатом должен быть экземпляр содержащий разность времени обоих операндов.
2.3. Создать бинарный оператор логического сравнения «==» экземпляров классов Car, результат
логического сравнения true, когда название бренда и цвет совпали у обоих операндов, иначе false.
2.4. Создать унарный оператор «++» который добавляет пройденный круг для машины.
3. Создать класс потомок класса RaceLap, в котором будет учитываться финальное время заезда (финальный протокол: RaceFinal), предусмотреть функции члены:
3.1. Конструктор на основе экземпляра класса гонка (Race).
3.2. Функция выбывания машины из заезда.
3.3. Функция добавление времени машине в заезде и круга машины в заезде.
3.4. Функция член для отображения результатов заезда (финального протокола).
Ход работы
Переведем структуру Car в класс и дополним его переменными, которые описывают количество кругов в заезде. Также перегрузим бинарные операторы суммы, разности и сравнения. Еще добавим перегрузку унарной операции суммирования. Заголовочный файл класса изображен на рисунке 1.
Рисунок 1 – заголовочный файл класса Car
Унарный оператор суммирования изображен на рисунке 2. Он копирует класс Car и увеличивает переменную lapCount на 1. Оператор изображен на рисунке 2.
Рисунок 2 – перегрузка унарного оператора суммы
Перегрузка бинарного оператора суммы изображена на рисунке 3. Класс присваивает все значения левого объекта к правому и увеличивает переменную raceTime.
Рисунок 3 – перегрузка бинарного оператора суммы
Бинарный оператор разности изображен на рисунке 4.
Рисунок 4 – перегрузка бинарного оператора разности
Бинарный оператор
сравнения изображен на рисунке 5. Он
делает проверку, что переменные rand
и color
совпадают. Возвращает true
или false.
Рисунок 5– перегрузка бинарного оператора сравнения
Для учета результатов всего заезда был создан класс RaceFinal, который наследуется от RaceLap. Заголовочный класс файла изображен на рисунке 6.
Рисунок 6 – заголовочный файл класса RaceFinal
Конструкторы класса изображены на рисунке 7.
Рисунок 7 – конструкторы класса RaceFinal
Метод addLap отвечает за добавление информации о новом круге, он изображен на рисунке 8. На вход он принимает RaceLap и количество машин, которые должны выбыть на очередном круге. На строках 15-20 происходит первичная инициализация состояния класса, если он еще не имеет информации о заездах. На 22 строке вызывается дружественный метод класса Race, чтобы удалить выбывшие машины из круга.
Рисунок 8 – метод addLap
Метод updateLap отвечает за обновление состояния вектора машин. С помощью перегруженных операторов он увеличивает переменные lapCount и raceTime. Метод изображен на рисунке 9.
Рисунок 9 – метод updateLap
Код метода finishLap изображён рисунке 10.
Рисунок 10 – метод finishLap.
После каждого добавленного круга переменная raceTime и lapCount класса Car изменяется и нужно сделать сортировку массива по количеству кругов и времени заезда. Сначала массив сортируется по убыванию lapCount, потом по возрастанию переменной raceTime. Сортировка происходит методом пузырька.
Главный метод main изображен на рисунке 11.
Рисунок 11 – метод main
Вывод программы изображен на рисунке 12.
Рисунок 12 – вывод программы
Вывод
В результате работы была изучена перегрузка бинарных операторов класса. Был создан класс RaceFinal, который отвечает за подсчет времени заезда каждой машины в гонке. Подсчет времени был осуществлен с помощью перегрузки операторов. Перегрузка операторов является полезной языковой возможностью в языке, она позволяет упростить код программы и сократить количество написанного кода.
ПРИЛОЖЕНИЕ
Код программы:
Файл car.h
#ifndef CAR_H
#define CAR_H
#include <string>
using namespace std;
class Car
{
public:
Car();
Car(string brand, string model, string color, float enginPower, float speed);
Car(const Car &car);
string toString();
friend Car operator+(const Car& car);
friend Car operator+(const Car& left, const Car& right);
friend Car operator-(const Car& left, const Car& right);
friend bool operator==(const Car& left, const Car& right);
string brand;
string model;
string color;
float enginPower;
float speed;
long raceTime;
bool isLeftRace = false;
int lapCount = 0;
};
#endif // CAR_H
Файл car.cpp
#include "car.h"
Car::Car()
{
}
Car::Car(string brand, string model, string color, float enginPower, float speed)
{ this->brand = brand;
this->model = model;
this->color = color;
this->enginPower = enginPower;
this->speed = speed;
}
Car::Car(const Car &car)
{
brand = car.brand;
model = car.model;
color = car.color;
enginPower = car.enginPower;
speed = car.speed;
isLeftRace = car.isLeftRace;
lapCount = car.lapCount;
raceTime = car.raceTime;
}
Car operator+(const Car& car)
{
Car modifiedCar = car;
modifiedCar.lapCount++;
return modifiedCar;
}
Car operator+(const Car& left, const Car& right)
{
Car car;
car.brand = left.brand;
car.model = left.model;
car.color = left.color;
car.speed = left.speed;
car.enginPower = left.enginPower;
car.isLeftRace = left.isLeftRace;
car.lapCount = left.lapCount;
car.raceTime = left.raceTime + right.raceTime;
return car;
}
Car operator-(const Car& left, const Car& right)
{
Car car;
car.brand = left.brand;
car.model = left.model;
car.color = left.color;
car.speed = left.speed;
car.enginPower = left.enginPower;
car.isLeftRace = left.isLeftRace;
car.lapCount = left.lapCount;
car.raceTime = left.raceTime - right.raceTime;
return car;
}
bool operator==(const Car& left, const Car& right)
{
return left.brand == right.brand && left.color == right.color;
}
string Car::toString()
{
return "brand: " + brand + ",\n" +
"model: " + model + ",\n" +
"color: " + color + ",\n" +
"engin power: " + to_string(enginPower) + ",\n" +
"speed: " + to_string(speed);
}
Файл race.h
#ifndef RACE_H
#define RACE_H
#include <car.h>
#include <vector>
#include <iostream>
#include <cstdlib>
#include <ctime>
const long MIN_RACE_TIME = 60 * 1000; // 00:60:00:000
const long MAX_RACE_TIME = 100 * 1000; // 01:40:00:000
class Race
{
public:
Race();
Race(int carCount);
~Race();
vector<Car> cars;
int carCount;
string getRaceResult();
void fillRace();
static int getTotalCarCount();
private:
static int totalCarCount;
Car getCar();
string formatTime(long raceTime);
};
#endif // RACE_H
Файл race.cpp
#include "race.h"
Race::Race() {
}
Race::Race(int carCount) {
this->carCount = carCount;
totalCarCount += carCount;
}
Race::~Race() {
cars.clear();
}
int Race::getTotalCarCount() {
return totalCarCount;
}
string Race::getRaceResult() {
string raceResult = "Total car count - " + to_string(carCount) + "\n";
for(int i = 0; i < carCount; i++) {
string inRaceBool;
if(cars[i].isLeftRace) inRaceBool = "false"; else inRaceBool = "true ";
raceResult += to_string(i + 1) +
": brand - " + cars[i].brand +
", model - " + cars[i].model +
", color - " + cars[i].color +
", speed - " + to_string(cars[i].speed) +
", in race - " + inRaceBool+
", lap count - " + to_string(cars[i].lapCount) +
", raceTime - " + formatTime(cars[i].raceTime) + "\n";
}
raceResult += "best time: " + formatTime(cars[0].raceTime) + "\n";
return raceResult;
}
void Race::fillRace() {
for(int i = 0; i < carCount; i++) {
cout << "inter " << i + 1 << " car data" << endl;
Car car = getCar();
cars.push_back(car);
}
}
Car Race::getCar() {
string str;
string brand;
string model;
string color;
float enginPower;
float speed;
cout << "input car brand: ";
cin >> brand;
cout << "input car model: ";
cin >> model;
cout << "input car color: ";
cin >> color;
while(true) {
cout << "input engin power: ";
cin >> str;
try {
enginPower = stof(str);
break;
} catch (...) {
cout << "invalid value" << endl;
}
}
while(true) {
cout << "input speed: ";
cin >> str;
try {
speed = stof(str);
break;
} catch (...) {
cout << "invalid value" << endl;
}
}
cout << endl;
Car car(brand, model, color, enginPower, speed);
return car;
}
string Race::formatTime(long raceTime) {
long milliseconds = raceTime % 1000;
long totalSeconds = raceTime / 1000;
long seconds = totalSeconds % 60;
long minutes = (totalSeconds / 60) % 60;
long hour = totalSeconds / 3600;
string millisecondsStr = to_string(milliseconds);
if(milliseconds < 10) {
millisecondsStr = "00" + to_string(milliseconds);
} else if(milliseconds < 100) {
millisecondsStr = "0" + to_string(milliseconds);
}
string secondsStr = to_string(seconds);
if(seconds < 10) {
secondsStr = "0" + secondsStr;
}
string minutesStr = to_string(minutes);
if(minutes < 10) {
minutesStr = "0" + minutesStr;
}
string hourStr = to_string(hour);
if(hour < 10) {
hourStr = "0" + hourStr;
}
return hourStr + ":" + minutesStr + ":" + secondsStr + ":" + millisecondsStr;
}
int Race::totalCarCount = 0;
Файл racelap.h
#ifndef RACELAB_H
#define RACELAB_H
#include <race.h>
class RaceLap: public Race
{
public:
RaceLap();
RaceLap(int carCount);
RaceLap(RaceLap &raceLap);
friend void removeLastCars(int count, RaceLap &raceLap);
private:
void fillLap();
};
#endif // RACELAB_H
Файл racelap.cpp
#include "racelap.h"
RaceLap::RaceLap(): Race() {
}
RaceLap::RaceLap(int carCount):Race(carCount) {
srand(time(NULL));
fillRace();
fillLap();
}
RaceLap::RaceLap(RaceLap &raceLap): Race(raceLap.carCount) {
cars = raceLap.cars;
fillLap();
}
void RaceLap::fillLap() {
// set random lap time for each car
for(int i = 0; i < carCount; i++) {
cars[i].raceTime = MIN_RACE_TIME + (rand() * rand()) % (MAX_RACE_TIME - MIN_RACE_TIME);
}
// sort cars array by raceTime
for(int i = 0; i < carCount; i++) {
for(int j = 0; j < carCount - i - 1; j++) {
if(cars[j].raceTime > cars[j+1].raceTime) {
Car swapCar = cars[j+1];
cars[j+1] = cars[j];
cars[j] = swapCar;
}
}
}
}
void removeLastCars(int count, RaceLap &raceLap) {
for(int i = 0; i < count; i++) {
raceLap.cars.pop_back();
}
raceLap.carCount -= count;
}
Файл racefinal.h
#ifndef RACEFINAL_H
#define RACEFINAL_H
#include <racelap.h>
class RaceFinal: public RaceLap
{
public:
RaceFinal();
RaceFinal(int carCount);
RaceFinal(RaceFinal &raceFinal);
void addLap(RaceLap &raceLap, int removeCarCount);
void finishLap();
private:
void updateLap(RaceLap &raceLap);
};
#endif // RACEFINAL_H
Файл racefinal.cpp
#include "racefinal.h"
RaceFinal::RaceFinal(): RaceLap() {
}
RaceFinal::RaceFinal(int carCount): RaceLap(carCount) {
}
RaceFinal::RaceFinal(RaceFinal &raceFinal): RaceLap(raceFinal) {
}
void RaceFinal::addLap(RaceLap &raceLap, int removeCarCount) {
if(cars.empty()) {
carCount = raceLap.cars.size();
for(int i = 0; i < raceLap.cars.size(); i++) {
cars.push_back(raceLap.cars[i]);
}
}
removeLastCars(removeCarCount, raceLap);
updateLap(raceLap);
finishLap();
}
void RaceFinal::updateLap(RaceLap &raceLap) {
bool isLeft;
for(int index = 0; index < cars.size(); index++) {
isLeft = true;
for(int lapIndex = 0; lapIndex < raceLap.cars.size(); lapIndex++) {
if(cars[index] == raceLap.cars[lapIndex]) {
cars[index] = cars[index] + raceLap.cars[lapIndex];
cars[index].lapCount++;
isLeft = false;
break;
}
}
cars[index].isLeftRace = isLeft;
}
}
void RaceFinal::finishLap() {
// sort array by lap count
for(int i = 0; i < cars.size(); i++) {
for(int j = 0; j < cars.size() - i - 1; j++) {
if(cars[j].lapCount < cars[j + 1].lapCount) {
Car swapCar = cars[j + 1];
cars[j + 1] = cars[j];
cars[j] = swapCar;
} else if(cars[j].lapCount == cars[j + 1].lapCount) {
if(cars[j].raceTime > cars[j + 1].raceTime) {
Car swapCar = cars[j + 1];
cars[j + 1] = cars[j];
cars[j] = swapCar;
}
}
}
}
}
Файл main.cpp
#include <iostream>
#include <race.h>
#include <racelap.h>
#include <racefinal.h>
using namespace std;
int main()
{
int count = 0;
cout << "input car count: ";
cin >> count;
RaceFinal raceFinal;
RaceLap raceLap1(count);
cout << "Start first lap" << endl;
raceFinal.addLap(raceLap1, 1);
cout << "Remove one last car in first lap" << endl;
cout << "Cars count in first lap: " << raceLap1.carCount << endl;
raceFinal.finishLap();
cout << "First lap result:" << endl << raceFinal.getRaceResult() << endl;
cout << "Start second lap" << endl;
RaceLap raceLap2 = raceLap1;
raceFinal.addLap(raceLap2, 2);
cout << "Remove two last car in second lap" << endl;
cout << "Cars count in second lap: " << raceLap2.carCount << endl;
raceFinal.finishLap();
cout << "Race result:" << endl << raceFinal.getRaceResult() << endl;
return 0;
}