лабы салапура / OOP-3 лаба отчет
.docxМинистерство образования Республики Беларусь
Министерство образования Республики Беларусь
БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
Кафедра эконмической информатики
Объектно-ориентированное программирование
Лабораторная работа №3
“ ДРУЖЕСТВЕННЫЕ ФУНКЦИИ И КЛАССЫ, ПЕРЕГРУЗКА ОПЕРАТОРОВ ”
Вариант 7
Выполнила: Студентка группы
972303
Рушева Маргарита
Владиславовна
Проверила: Григорьева Юлия
Юрьевна
Минск, 2020
1 ЦЕЛЬ ЛАБОРАТОРНОЙ РАБОТЫ
Понять назначение дружественных функций и классов, изучить принципы перегрузки бинарных и унарных операций.
2 ТЕОРИЯ ПО ЛАБОРАТОРНОЙ РАБОТЕ
ДРУЖЕСТВЕННЫЕ ФУНКЦИИ
Иногда возникает необходимость в организации доступа к локальным данным нескольких классов из одной функции. Для реализации этого в язык С++ введен спецификатор friend. Если некоторая функция определена как friend-функция для некоторого класса, то эта функция называется дружественной и она:
не является компонентом-функцией этого класса;
имеет доступ ко всем компонентам этого класса (private, public, protected).
Функции со спецификатором friend, не являясь компонентами класса, не имеют и, следовательно, не могут использовать this указатель. В общем случае friend-функция является глобальной независимо от секции, в которой она объявлена (public, protected, private), при условии, что она не объявлена ни в одном другом классе без спецификатора friend. Все функции одного класса можно объявить со спецификатором friend по отношению к другому классу следующим образом.
Основные свойства и правила использования спецификатора friend: friend-функции не являются компонентами класса, но имеют доступ ко всем его компонентам независимо от их атрибута доступа. Дружественная функция может располагаться в любом блоке класса – private, public, protected. Она при любых обстоятельствах будет иметь доступ к privateэлементам класса и, даже если она сама находится в поле private, к ней можно будет обратиться вне класса, не используя специальных методов; элементы класса необходимо явно передавать во friend-функцию в виде параметров функции. Так как friend-функция не является компонентом класса, она не получает указатель this; friend-функции не наследуются в производных классах; отношение friend не является ни симметричным (если класс А friend классу В, то это не означает, что В также является friend классу А), ни транзитивным (т. е. если A friend B и B friend C, то не следует, что A friend C); друзьями класса можно определить перегруженные функции; функция может использоваться, как дружественная к нескольким классам. функцию, объявленную со спецификатором friend нельзя объявлять виртуальной.
ПЕРЕГРУЗКА ОПЕРАТОРОВ
Пересечение множеств в теории множеств — это множество, которому принадлежат те и только те элементы, которые одновременно принадлежат всем данным множествам.
Объединение множеств (сумма или соединение) в теории множеств — множество, содержащее в себе все элементы исходных множеств.
Для того, чтобы определить, какую функцию должен выполнять оператор: старую или новую, необходимо посмотреть на тип операндов в соответствующем выражении.
Перегружать можно только предопределенные операторы языка C++. Проектировщик класса не вправе объявить перегруженным оператор с другим именем.
Следующие операторы языка C++ не могут быть перегружены:
:: (оператор расширения области видимости);
.* (доступ к элементу класса по указателю);
. (доступ к элементу);
?: (тернарный оператор);
# (оператор преобразования в строку);
## (оператор двойного числа или маркера, оператор слияния);
sizeof (оператор нахождения размера объекта в байтах).
ФУНКЦИЯ OPERATOR
Функция operator может быть использована для перегрузки операторов, таких как «+», «-», «*», «%», «&», «|» и др. Для перегрузки (доопределения) оператора разрабатываются функции, являющиеся либо компонентами, либо friend-функциями того класса, для которого они используются. Для того чтобы перегрузить оператор, требуется определить действие этого оператора внутри класса.
Перегрузка операторов не изменяет порядок выполнения операций и их приоритет.
Унарный оператор не может использоваться для переопределения бинарной операции так же, как и бинарный оператор не переопределит унарную операцию.
Предопределенное назначение оператора нельзя изменить для встроенных типов. Нельзя также определять дополнительные операторы для встроенных типов данных, например добавить к множеству встроенных операций operator+ для сложения двух массивов.
РАЗРАБОТКА ПЕРЕГРУЖЕННЫХ ОПЕРАТОРОВ КЛАССА
После определения открытого интерфейса класса проверьте, есть ли логическое соответствие между операциями и операторами: • isEmpty() становится оператором “ЛОГИЧЕСКОЕ НЕ”, operator!(). • isEqual() становится оператором равенства, operator==(). • copy() становится оператором присваивания, operator=().
3 ИНДИВИДУАЛЬНОЕ ЗАДАНИЕ
Реализовать класс String для работы со строками символов. Перегрузить оператор «-» (минус) так, чтобы определить, насколько одна строка длиннее другой. Перегрузить оператор «>», так, чтобы возвратить разность кодов первой пары несовпадающих символов в строках. Перегрузить унарные операторы «++» (префиксную и постфиксную). Реализовать конструкторы (по умолчанию, с параметрами, копирования), деструктор. Определить friend-функции для операторов ввода/вывода в поток.
4 КОД РЕШЕНИЯ ИНДИВИДУАЛЬНОГО ЗАДАНИЯ
#include<math.h>
#include <iostream>
#include <conio.h>
using namespace std;
class String
{
char* str; // указатель на строку
char* Conact(const char* one, const char* two)
{
char* three = new char[strlen(one) + strlen(two) + 1]{ '\0' };
strcat_s(three, strlen(one) + 1, one);
strcat_s(three, strlen(one) + strlen(two) + 1, two);
return three;
}
public:
// конструктор по умолчанию
String()
{
str = NULL;
}
// конструктор с параметрами
String(const char* one)
{
str = Conact("", str);
}
// конструктор копирования
String(const String& s)
{
str = Conact("", s.str);
}
//деструктор
~String()
{
delete str;
}
//оператор «-»
int operator-(const String& s)
{
return strlen(this->str) - strlen(s.str);
}
//Перегрузить оператор «>»
int operator>(const String& s)
{
int n = strlen(this->str), m = strlen(s.str);
for (int i = 0; i < n && i < m; i++)
if (str[i] != s.str[i])
return str[i] - s.str[i];
if (n > m)
return str[m];
if (n < m)
return s.str[n];
return 0;
}
//префикс
String& operator++()
{
this->str = Conact(" ", str);
return *this;
}
//постфикс
String operator++(int)
{
this->str = Conact(str, " ");
return *this;
}
friend ostream& operator<< (ostream& out, const String& s);
friend istream& operator >> (istream& in, String& s);
};
ostream& operator<< (std::ostream& out, const String& s)
{
setlocale(LC_ALL, "Russian");
out << s.str;
return out;
}
istream& operator >> (istream& in, String& s)
{
setlocale(LC_ALL, "Russian");
char* tmp = new char[9999];
in.getline(tmp, 9999);
s.str = s.Conact("", tmp);
delete[] tmp;
return in;
}
int main()
{
int q;
char ch;
while(true)
{
setlocale(LC_ALL, "Russian");
String a, b;
cout << "Введите строку: ";
cin >> a;
cout << "Введите вторую строку: ";
cin >> b;
cout << "S1 = " << a << endl;
cout << "S2 = " << b << endl;
cout << "S1-S2 = " << a - b << endl;
cout << "S1>S2 = " << (a > b) << endl;
++a; ++a; ++a;
cout << "++s1 = " << a << endl;
++b; ++b; ++b;
cout << "++s2 = " << b << endl;
a++; a++; a++;
cout << "s1++ = " << a << endl;
b++; b++; b++;
cout << "s2++ = " << b << endl;
system("pause");
cout << "Хотите продолжить ввод данных?" << endl;
cout << "1 - да" << endl;
cout << "2 - нет, выйти" << endl;
cout << "Ваш выбор:" << endl;
ch = _getch();
cout << ch << endl;
q = atoi(&ch);
if (q == 1)
{
continue;
}
else if (q == 2)
{
break;
}
}
return 0;
}
5 СКРИНШОТЫ ВЫПОЛНЕНИЯ ИНДИВИДУАЛЬНОГО ЗАДАНИЯ
ВЫВОДЫ
В ходе выполнения лабораторной работы была изучена организация ввода/вывода данных. Работа над лабораторной работой позволила научится работать с динамической памятью при программировании алгоритмов на языке C++, работать с манипуляторами. Была разработана программа с использованием новых понятий, изученных в лабораторной работе.