Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МВ_Прог_1курс_2часть.doc
Скачиваний:
8
Добавлен:
09.09.2019
Размер:
1.02 Mб
Скачать

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

4.1 Мета роботи

4.2 Вказівки щодо організації самостійної роботи студентів

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

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

?: :: # # sizeof

Перегрузка операций осуществляется с помощью методов специального вида (функций-операций) и подчиняется следующим правилам:

- при перегрузке операций сохраняются количество аргументов, приоритеты операций и правила ассоциации (справа налево или слева направо), используемые в стандартных типах данных;

- для стандартных типов данных переопределять операции нельзя;

- функции-операции не могут иметь аргументов по умолчанию;

- функции-операции наследуются (за исключением =);

- функции-операции не могут определяться как static.

Функция-операция содержит ключевое слово operator, за которым следует знак переопределяемой операции:

тип operator операция ( список параметров) { тело функции }

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

struct Tstud

{

char FIO[20];

int bal;

};

struct TAB

{

float A;

int B;

};

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

Перегрузим операции “++” и “--”.

Поскольку операция унарная в качестве аргументов передается один параметр:

Tstud& operator ++(Tstud &Stud)

{

++Stud.bal;

return Stud;

}

Tstud& operator --(Tstud &Stud)

{

--Stud.bal;

return Stud;

}

Теперь для переменных (объектов) типа Tstud можно использовать операции инкремент и декремент:

Tstud Student={"Ivanov",3};

++Student;// Student={"Ivanov",4}

--Student--;// Student={"Ivanov",2}

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

Перегрузим операцию “+” для структуры TAB. Поскольку операция бинарная в качестве аргументов передается два параметра:

TAB operator +(const TAB &operand1,const TAB &operand2)

{TAB AB;

AB.A=operand1.A+operand2.A;

AB.B=operand1.B+operand2.B;

return AB;}

Пример использования:

TAB AB1={1.3,2},AB2={2.1,1};

TAB AB3=AB1+AB2; // AB3={3.4,3};

Теперь перегрузим операцию “>” для структуры Tstud. Будем считать, что левый операнд «больше» правого если его поле «bol» больше поля «bol» правого операнда. Результат этой операции должен быть логического типа:

bool operator >(const Tstud &Stud1, const Tstud &Stud2)

{return Stud1.bal>Stud2.bal;}

Пример использования:

Tstud Stud1={"Petrov",3};

Tstud Stud2={"Sidorov",2};

if(Stud1>Stud2)cout<<">"<<endl;

else cout<<"<"<<endl;

Перегрузка следующих операций должна быть осуществлена внутри описания объекта

Перегрузка операции приведения типа

Можно определить функции-операции, которые будут осуществлять преобразование объекта класса к другому типу. Формат:

operator имя_новоготипа ();

Тип возвращаемого значения и параметры указывать не требуется.

Перегрузка операции вызова функции

Формат:

тип operator () (список параметров);

Для примера определим оператор приведения типа int и определим оператор вызова функции, который задает поля структуры:

struct Tstud

{

char FIO[20];

int bal;

operator int() {return (bal); }

void operator()(char* str,int mybal)

{

strcpy(FIO,str);

bal=mybal;

}

};

Пример вызова:

Stud2("Petja",5); // Stud2={"Petja",5}

cout<<(int)Stud2<<endl;// на экран будет выведенно число 5

Потоки и типы, определенные пользователем

Для ввода и вывода в потоках используются перегруженные для всех стандартных типов операции чтения и извлечения << и >>. При этом выбор конкретной операции определяется типом фактических параметров. Для того чтобы вводить и выводить величины типов, определенных пользователем, требуется перегрузить эти операции. Это бинарные операции, левым операндом которых является объект-поток, а правым - объект, который требуется извлечь или поместить в этот поток. Возвращаемое значение должно быть ссылкой на поток, чтобы можно было организовывать цепочки операций, как и в случае стандартных типов.

Формат определения собственной функции вставки:

ostream& operator<<(ostream& имя_потока, Тип объект)

{

Тело функции вставки

return имя_потока;

}

Формат определения собственной функции извлечения:

istream& operator>>(istream& имя_потока, Тип объект)

{

Тело функции вставки

return имя_потока;

}

Определим собственные функции вставки и извлечения для структуры Tstud:

ostream& operator<<(ostream& out,const Tstud &Stud)

{

out<<setw(10)<<setfill('.')<<setiosflags(ios::left)<<Stud.FIO

<<Stud.bal<<endl;

return out;

}

istream& operator>>(istream& in,Tstud &Stud)

{

cout<<"Vvedite FIO\n";

in>>Stud.FIO;

cout<<"Vvedite Bal\n";

in>>Stud.bal;

return in;

}

Пример использования:

Tstud Stud;

cin>>Stud;

cout<<Stud;

В результате будут вызваны функции определенные пользователем.

4.3 Порядок виконання роботи

4.4 Контрольні запитання та завдання

4.5 Завдання

Определить основные операции для структуры, перегрузить операции работы с потоками ввода и вывода.

4.6 Варіанти завдань

Описания структур взять из лабораторной работы №2

4.7 Контрольний приклад

Определить операции ++, --, >, +, (), приведение к типу int, а также перегрузить операции работы с потоком для структуры студент.

#include <iostream>

#include <fstream>

#include <iomanip>

#include <string>

using namespace std;

struct Tstud{

char FIO[20];

int bal;

operator int() const {return (bal); }

void operator()(char* str,int mybal)

{

strcpy(FIO,str);

bal=mybal;

}

};

Tstud& operator ++(Tstud &Stud)

{

++Stud.bal;

return Stud;

}

Tstud& operator --(Tstud &Stud)

{

--Stud.bal;

return Stud;

}

Tstud operator +( const Tstud &Stud1, const Tstud &Stud2)

{

Tstud Stud=Stud1;

strcat(Stud.FIO,Stud2.FIO);

Stud.bal+=Stud2.bal;

return Stud;

}

bool operator >(const Tstud &Stud1, const Tstud &Stud2)

{

return Stud1.bal>Stud2.bal;

}

ostream& operator<<(ostream& out,Tstud &Stud)

{

out<<setw(20)<<setfill('.')<<setiosflags(ios::left)<<Stud.FIO<<Stud.bal;

return out;

}

istream& operator>>(istream& in,Tstud &Stud)

{

cout<<"Vvedite FIO\n";

in>>Stud.FIO;

cout<<"Vvedite Bal\n";

in>>Stud.bal;

return in;

}

int main()

{

Tstud Student1={"Ivanov",3};

Tstud Student2={"Petrov",5};

Tstud Student3;

Student1--;//Student1={"Ivanov",2};

Student2++;//Student2={"Petrov",6};

cout<<Student1<<endl;

cout<<Student2<<endl;

Student3=Student1+Student2;//Student3={"IvanovPetrov",8};

cout<<Student3<<endl;

Student3("Sidorov",5);//Student3={"Sidorov",5};

cout<<Student3<<endl;

if(Student1>Student2)

cout<< Student1.FIO<<" u4itsj lu4she "<<Student2.FIO<<endl;

else cout<< Student2.FIO<<" u4itsj lu4she "<<Student1.FIO<<endl;

const int n=3;

Tstud StudentMas[n];

//организуем ввод и вывод массива структур

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

cin>>StudentMas[i];

//Вывод на экран

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

cout<<StudentMas[i]<<endl;

//Вывод в файл

ofstream out("f.txt");

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

out<<StudentMas[i]<<endl;

cin.get();

return 0;

}

Результаты работы программы:

Ivanov……….2

Petrov………..6

Ivanov Petrov..8

Sidorov………5

Petrov u4itsj lu4she Ivanov

Vvedite FIO

Петров

Vvedite Bal

2

Vvedite FIO

Сидоров

Vvedite Bal

5

Vvedite FIO

Максименко

Vvedite Bal

3

5 Основи розробки класів у мові С++