Министерство образования Республики Беларусь Учреждение образования БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
Лабораторная работа №4 по предмету объектно-ориентированное программирование
Выполнил: студент гр. 672302 Климович К.А. Проверил: Салапура М.Н.
Минск 2018 Вариант №3 Задание: Реализовать класс String для работы со строками символов. Перегрузить операторы =, += так, чтобы производилось сложение строки и объекта. Предоставить кон-структор копирования.
Теория:
Программы на языке С++ используют некоторые ранее определенные простейшие классы (типы), такие, как int, char, float и т. д.
Пересечение множеств в теории множеств — это множество, которому принадлежат те и только те элементы, которые одновременно принадлежат всем данным множествам.
Объединение множеств (сумма или соединение) в теории множеств — множество, содержащее в себе все элементы исходных множеств.
Функция operator может быть использована для расширения области приложения следующих операторов: «+», «-», «*», «%», «&», «|» и т.д. Оператор # (диез, символ препроцессора) так же не может быть перегружен. Так же не могут быть перегружены операторы sizeof (оператор нахождения размера объекта в байтах) и typeid (оператор «интроспекция», (type introspection) определяет возможность определить тип и структуру объекта во время выполнения программы).
Унарный оператор не может использоваться для переопределения бинарной операции так же, как и бинарный оператор не переопределит унарную операцию.
Предопределенное назначение оператора нельзя изменить для встроенных типов. Нельзя также определять дополнительные операторы для встроенных типов данных, например добавить к множеству встроенных операций operator+ для сложения двух массивов.
Бинарный оператор можно определить либо в виде нестатической функции-члена с одним аргументом, либо в виде функции-не-члена с двумя аргументами. Для любого бинарного оператора @ выражение aa@bb интерпретируется либо как aa.operator@(bb), либо как operator@(aa,bb). Если бинарный оператор перегружается с помощью функции-члена, то в качестве своего первого аргумента он получает неявно переданную переменную класса, а второго – единственный из списка аргументов. При объявлении функции-не-члена, чаще всего используют friend-функции, в списке параметров определяют оба аргумента.
Оба параметра явно определяются и являются кандидатами для преобразования назначением. Используя это определение, имеем:
int i=5; clock c(100); c+i; // допустимо: i – преобразуется в clock::operator+(c,clock(i)) i+c; // допустимо: i – преобразуется в clock::operator+(clock(i),c)
В противоположность этому, перегрузим двухместный – функцией-членом.
Определим операцию умножения long и clock как дружественную функцию
class clock { friend clock operator*(long m, const clock &c); }; clock operator *(long m, const clock &c) { clock temp(m*c.sec); return temp; }
Такая реализация вынуждает операцию умножения иметь фиксированный порядок выполнения, зависящий от типа. Для избежания этого обычно пишется второй перегруженный функциональный оператор.
class clock { friend clock operator*(long m, const clock &c); friend clock operator*(const clock &c, long m); }; clock operator *(const clock &c, long m) { clock temp(m*c.sec); return temp; }
operator=, operator[] и operator-> должны быть нестатическими функциями-членами. Это гарантирует, что их первый операнд будет lvalue. Некоторые встроенные операторы определены таким образом, что они эквивалентны некоторой комбинации других операторов. Например, ++a означает, что a+=1, что в свою очередь означает, a=a+1. Такая связь не сохраняется в операторах, определяемых пользователем. То есть компилятор не сгенерирует z::operator+=() из z::operator+() и z::operator=().
Код:
#include <iostream> #include <string.h> #pragma warning(disable:4996) using namespace std;
class String { char *str; int len; public: String() {} String(const char* s) //конструктор с параметрами { len = strlen(s); str = new char[len + 1]; //выделяем память под строку for (int i = 0; i <= len; i++) str[i] = s[i]; //заполняем строку символами } String(const String &obj) //конструктор копирования { len = obj.len; str = new char[len + 1]; strcpy(str, obj.str); } void operator += (String& str1) //перегрузка оператора += { strcat(str, str1.str); } String operator = (const String& str1) //перегрузка оператора = { str = new char[str1.len]; strcpy(str, str1.str); return *this; } void print() //вывод строки { puts(str); } ~String() {} };
int main() { char s1[255], s2[255]; cout << "Input 1st string: "; gets_s(s1); //вводим 1-ю строку cout << "Input 2nd string: "; gets_s(s2); //вводим 2-ую строку String str1(s1), str2(s2), str3; //создаем 3 объекта класса, первые два заполняем введенными строками, третий пустой str1 += str2; //добавляем вторую строку у первой cout << "+= result: "; str1.print(); //выводим результат присоедеинения str3 = str2; //присваиваем пустой строке значение второрй cout << "= result: "; str3.print(); //выводим результат присваивания system("pause"); return 0; }