Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
МВ_Прог_1курс_2n1часть.doc
Скачиваний:
11
Добавлен:
13.04.2015
Размер:
735.74 Кб
Скачать

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;

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