Пример. Цель работы:приобрести навыки в использовании перегрузки операций

Лабораторная работа №4

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

 

Цель работы:приобрести навыки в использовании перегрузки операций.

Задание: Согласно условию определить класс, который должен включать в себя перегружаемый оператор >> для ввода данных с консоли с обязательной проверкой на корректность вводимых данных, перегружаемый оператор << вывода данных, перегружаемые операторы приведения объектов к стандартным типам int и double, перегружаемые операторы сравнения (==, >, >=, <, <=, !=), а также указанные в задании перегружаемые операторы. Число, записанное в объекте, должно быть произвольной длины. Это означает, что оно не обязательно поместится в разрядную сетку известных числовых форматов. Поэтому для реализации операций потребуется разработка собственного алгоритма. Операторы ввода и вывода данных должны быть реализованы в виде дружественных функций, все остальные операторы – в виде методов класса.

 

Пример.

Условие задачи.Создать класс, который хранит целое троичное число без знака. Перегрузить операции +, ++, +=.

 

#include <iostream>

using namespace std;

 

class Number

{

int *digits; // Массив для хранения троичного числа

int count; // Текущее количество разрядов

 

void setDigits(char *str)

{

// Если число уже было в массиве - удаляем его

if (this->digits != NULL)

delete[] digits;

 

int len = strlen(str);

int pos = 0;

 

// Пропустить ведущие нули (если они есть)

while (pos < len && str[pos] == '0')

pos++;

 

if (pos >= len)

{

// Отдельно обрабатываем случай, когда вся

// строка состоит из одних нулей

this->count = 1;

this->digits = new int[1];

this->digits[0] = 0;

return;

}

 

this->count = len - pos;

this->digits = new int[this->count];

 

for (int i=0; i<this->count; i++)

this->digits[i] = (int)str[i + pos] - (int)'0';

 

return;

}

 

int SubNumber(Number n)

{

// Вспомогательный метод, сравнивает текущее число с n

// Возвращает 0 - если оба числа равны

// 1 - если текущее число больше

// -1 - если текущее число меньше

 

// Если количество цифр у одного из чисел больше -

// значит и само число больше

 

if (this->count > n.count)

return 1;

 

if (this->count < n.count)

return -1;

 

// Если количество цифр одинаковое, выполняем

// вычитание "столбиком".

// Результат вычитания при этом не сохраняем,

// так как для вычисления результата

// требуется знать есть ли заем и есть ли значащие

// цифры в результате

 

int perenos = 0;

int result = 0;

 

int resr;

for (int i = this->count - 1; i >= 0; i--)

{

resr = this->digits[i] - n.digits[i] - perenos;

if (resr < 0)

{

result |= resr + 3;

perenos = 1;

}

else

{

result |= resr;

perenos = 0;

}

}

 

// Оба числа равны, если нет заема и результат равен нулю

if (perenos == 0 && result == 0)

return 0;

 

// Tекущее число больше n, если заема нет и

// результат не равен нулю

if (perenos == 0 && result != 0)

return 1;

 

// Иначе текущее число меньше n

return -1;

}

 

char* AddNumber(Number n)

{

// Вспомогательный метод, складывает текущее число с n

// и возвращает новое число в качестве результата (в виде строки)

 

int MaxLength = (this->count > n.count) ? this->count : n.count;

 

// Выделяем память для хранения результата

// результат может быть на 1 разряд больше

// еще 1 символ нужен для хранения завершающего нуля строки

char *str = new char[MaxLength + 2];

 

// Забиваем всю строку нулями

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

str[i] = '0';

 

// Признак конца строки

str[MaxLength+1] = 0;

 

int perenos = 0;

int resr, cha, chb;

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

{

cha = (i < this->count) ? this->digits[this->count - i - 1] : 0;

chb = (i < n.count ) ? n.digits[n.count - i - 1] : 0;

resr = cha + chb + perenos;

 

perenos = resr / 3;

str[MaxLength - i] = (char)((resr % 3) + '0');

}

if (perenos != 0)

str[0] = (char)(perenos + '0');

 

return str;

}

 

public:

Number()

{

this->digits = NULL;

this->count = 0;

}

 

Number(char *str)

{

this->digits = NULL;

this->count = 0;

this->setDigits(str);

}

 

// дружественная функция для ввода числа

friend istream & operator>>(istream &input, Number &num);

 

// дружественная функция для вывода числа

friend ostream & operator<<(ostream &output, Number &num);

 

operator int()

{

if (this->digits == NULL)

return 0;

 

int result = 0;

 

for (int i=0; i<this->count; i++)

{

result *= 3;

result += this->digits[i];

}

 

return result;

}

 

operator double()

{

if (this->digits == NULL)

return 0.0;

 

double result = 0.0;

 

for (int i=0; i<this->count; i++)

{

result *= 3.0;

result += this->digits[i];

}

 

return result;

}

 

bool operator == (Number &n)

{

int res = this->SubNumber(n);

return (res == 0) ? true : false;

}

 

bool operator != (Number &n)

{

int res = this->SubNumber(n);

return (res != 0) ? true : false;

}

 

bool operator > (Number &n)

{

int res = this->SubNumber(n);

return (res == 1) ? true : false;

}

 

bool operator >= (Number &n)

{

int res = this->SubNumber(n);

return (res == 0 || res == 1) ? true : false;

}

 

bool operator <= (Number &n)

{

int res = this->SubNumber(n);

return (res == 0 || res == -1) ? true : false;

}

 

bool operator < (Number &n)

{

int res = this->SubNumber(n);

return (res == -1) ? true : false;

}

 

Number operator + (Number &n)

{

return Number(this->AddNumber(n));

}

 

void operator += (Number &n)

{

this->setDigits(this->AddNumber(n));

}

 

Number operator ++(int)

{

this->setDigits(this->AddNumber(Number("1")));

return *this;

}

};

 

istream & operator>>(istream &input, Number &num)

{

const int dsize = 10;

int size = 0;

int msize = dsize;

char *str = (char*)malloc(msize + 1);

char c;

 

/* Ввод данных */

do {

// Читаем один символ

input.get(c);

 

// Если встретили конец строки

if (c == '\n' || c == '\0') break;

 

// Сохраняем прочитанный символ в строке

str[size] = c;

size++;

 

// Если текущий размер выделенной памяти меньше

// длины строки - перераспределяем память

if (size >= msize)

{

msize+=dsize;

str = (char*)realloc(str, msize + 1);

}

} while (1);

 

str[size]=0;

 

/* Проверка введенных данных на корректность */

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

{

if (str[i]< '0' || str[i] > '2')

{

cout << "Incorrect input" << endl;

free(str);

return input;

}

}

 

/* Инициализация объекта Number */

num.setDigits(str);

 

free(str);

return input;

}

 

ostream & operator<<(ostream &output, Number &num)

{

if (num.digits != NULL)

{

for (int i=0; i<num.count; i++)

output << num.digits[i];

 

output << endl;

}

 

return output;

}

 

int main()

{

Number a,b,c;

int action;

 

while (1)

{

// Меню

system("cls");

 

cout<<"Main menu (0 - exit)" <<endl<<

"1. Input A"<<endl<<"2. Input B"<<endl<<"3. Output A"<<endl<<

"4. Output B"<<endl<<"5. Output C"<<endl<<endl<<"6. A==B"<<endl<<

"7. A!=B"<<endl<<"8. A>B"<<endl<<"9. A<B"<<endl<<

"10. A>=B"<<endl<<"11. A<=B"<<endl<<"12. A++"<<endl<<

"13. B++"<<endl<<"14. A+=B"<<endl<<"15. C=A+B"<<endl;

 

// Выбор действия

cin>>action; cin.clear(); cin.sync();

 

switch (action)

{

case 0: return 0;

case 1: cout<<"Input A, please: "; cin>>a; break;

case 2: cout<<"Input B, please: "; cin>>b; break;

case 3: cout<<"Number A: " << a; cin.get(); break;

case 4: cout<<"Number B: " << b; cin.get(); break;

case 5: cout<<"Number C: " << c; cin.get(); break;

case 6: cout<<"A==B: " << ((a==b) ? "Yes" : "No"); cin.get(); break;

case 7: cout<<"A!=B: " << ((a!=b) ? "Yes" : "No"); cin.get(); break;

case 8: cout<<"A>B: " << ((a>b) ? "Yes" : "No"); cin.get(); break;

case 9: cout<<"A<B: " << ((a<b) ? "Yes" : "No"); cin.get(); break;

case 10: cout<<"A>=B: " << ((a>=b) ? "Yes" : "No"); cin.get(); break;

case 11: cout<<"A<=B: " << ((a<=b) ? "Yes" : "No"); cin.get(); break;

case 12: cout<<"A++: "; a++; cout<<a; cin.get(); break;

case 13: cout<<"B++: "; b++; cout<<b; cin.get(); break;

case 14: cout<<"A+=B: "; a+=b; cout<<a; cin.get(); break;

case 15: cout<<"C=A+B: "; c=a+b; cout<<c; cin.get(); break;

}

 

}

 

return 0;

}

 

 


Содержание отчёта

 

1. Титульный лист.

2. Условие лабораторной работы.

3. Текст программы.

4. Экранные формы с примерами работы программы.

 

Варианты заданий.

 

1. Создать класс, который хранит целое десятичное число со знаком. Перегрузить операции +, ++, +=.

 

2. Создать класс, который хранит целое десятичное число без знака. Перегрузить операции +, ++, +=.

 

3. Создать класс, который хранит целое десятичное число со знаком. Перегрузить операции -, --, -=.

 

4. Создать класс, который хранит целое десятичное число без знака. Перегрузить операции -, --, -=.

 

5. Создать класс, который хранит целое десятичное число со знаком. Перегрузить операции *, *=.

 

6. Создать класс, который хранит целое десятичное число без знака. Перегрузить операции *, *=.

 

7. Создать класс, который хранит целое шестнадцатеричное число со знаком. Перегрузить операции +, ++, +=.

 

8. Создать класс, который хранит целое шестнадцатеричное число без знака. Перегрузить операции +, ++, +=.

 

9. Создать класс, который хранит целое шестнадцатеричное число со знаком. Перегрузить операции -, --, -=.

 

10. Создать класс, который хранит целое шестнадцатеричное число без знака. Перегрузить операции -, --, -=.

 

11. Создать класс, который хранит целое шестнадцатеричное число со знаком. Перегрузить операции *, *=.

 

12. Создать класс, который хранит целое шестнадцатеричное число без знака. Перегрузить операции *, *=.

 

13. Создать класс, который хранит целое восьмеричное число со знаком. Перегрузить операции +, ++, +=.

 

14. Создать класс, который хранит целое восьмеричное число без знака. Перегрузить операции +, ++, +=.

 

15. Создать класс, который хранит целое восьмеричное число со знаком. Перегрузить операции -, --, -=.

 

16. Создать класс, который хранит целое восьмеричное число без знака. Перегрузить операции -, --, -=.

 

17. Создать класс, который хранит целое восьмеричное число со знаком. Перегрузить операции *, *=.

 

18. Создать класс, который хранит целое восьмеричное число без знака. Перегрузить операции *, *=.

 

19. Создать класс, который хранит целое двоичное число со знаком. Перегрузить операции +, ++, +=.

 

20. Создать класс, который хранит целое двоичное число без знака. Перегрузить операции +, ++, +=.

 

21. Создать класс, который хранит целое двоичное число со знаком. Перегрузить операции -, --, -=.

 

22. Создать класс, который хранит целое двоичное число без знака. Перегрузить операции -, --, -=.

 

23. Создать класс, который хранит целое двоичное число со знаком. Перегрузить операции *, *=.

 

24. Создать класс, который хранит целое двоичное число без знака. Перегрузить операции *, *=.

 

25. Создать класс, который хранит целое римское число со знаком. Перегрузить операции +, ++, +=.

 

26. Создать класс, который хранит целое римское число без знака. Перегрузить операции +, ++, +=.

 

27. Создать класс, который хранит целое римское число со знаком. Перегрузить операции -, --, -=.

 

28. Создать класс, который хранит целое римское число без знака. Перегрузить операции -, --, -=.

 

29. Создать класс, который хранит целое римское число со знаком. Перегрузить операции *, *=.

 

30. Создать класс, который хранит целое римское число без знака. Перегрузить операции *, *=.