Перезавантаження бінарних операцій 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Перезавантаження бінарних операцій



Бінарні операції можуть бути перезавантажені так само, як унарні. Ми розглянемо приклади перезавантаження арифметичних операцій, операцій порівняння та операції присвоювання.

 

Арифметичні операції

В програмі 11.5 ми розглядали два об’єкти класу Distance, які додавалися за допомогою методу add_dist()

dist3.add_dist(dist1,dist2);

Використовуючи перезавантаження операції +, ми можемо записати подібний вираз зрозуміліше:

dist3=dist1+dist2

Ця можливість реалізована в лістінгу програми 10.5

#include <iostream.h>

#include <conio.h>

#include <bios.h>

class Distance

{private:

int feet;

float inches;

public:

 

Distance():feet(0),inches(0.0) //конструктор без параметрів

{ }

 

//конструктор з 2 параметрами

Distance(int ft,float in):feet(ft),inches(in)

{ }

 

void getdist()

{cout <<”\nВведіть число футів “; cin >>feet;

cout << “дюймів “; cin>>inches;

}

 

void showdist()

{cout <<feet << “\’ “<< inches <<”\’’”;}

 

Distance operator+(Distance) const;

};

 

//Додавання d2 I d3

Distance Distance::operator+(Distance d2) const

{

 int f=feet+d2.feet;

 float i=inches+d2.inches;

 if(i>=12.0)

 {i-=12.0;

 f++;}

 return Distance(f,i);

}

 

int main()

{

clrscr();

Distance dist1,dist3,dist4;

dist1.getdist();

 

Distance dist2(11,6.25);

 

dist3=dist1+dist2;

dist4=dist1+dist2+dist3;

cout <<”\ndist1=”;dist1.showdist();

cout << “\ndist2=”;dist2.showdist();

cout << “\ndist3=”;dist3.showdist();

cout << “\ndist4=”;dist4.showdist();

cout <<endl;

bioskey(0);

return 0;

}

Програма 10.5

Для того, щоб показати, що результат додавання може бути використаний в інших операціях, ми виконали в функції main() такі дії: додали dist1, dist2, dist3, одержавши dist4.

Оголошення методу operator+() в класі Distance виглядає так:

Distance Distance::operator+(Distance d2)

Ця операція повертає значення типу Distance і приймає один аргумент типу Distance.

У виразі

dist=dist1+dist2

важливо розуміти, до яких об’єктів відноситимуться аргументи і значення, що повертаються. Коли компілятор зустрічає цей вираз, він проглядає типи аргументів. Виявивши лише аргументи типу Distance, він виконує операції виразу, використовуючи метод класу Distance operator+(). Але який з об’єктів використовується в якості аргументу цієї операції – dist1 чи dist2? Чи не потрібно нам використовувати два аргументи, оскільки ми додаємо два об’єкти?

Існує правило: об’єкт з лівої сторони операції (в нашому випадку dist1)б викликає функцію оператора. Об’єкт, що стоїть справа від знаку операції, повинен бути переданий в функцію у якості аргумента. Операція повертає значення, яке ми потім використовуємо для своїх потреб.

В функції operator+() до лівого операнда ми маємо прямий доступ, використовуючи feet та inches, оскільки це об’єкт, що викликає функцію. До правого операнда ми маємо доступ як до аргументу функції, тобто як d2.feet та d2.inches.

Ми можемо узагальнити раніше викладене і сказати, що перезавантаженій операції завжди потрібно на 1 менше аргументів, ніж кількість операндів, оскільки один з операндів є об’єктом, що викликає функцію. Тому для унарних операцій не потрібні аргументи (крім функцій та операторів, дружніх до класу, яку ми вивчатимемо в майбутньому).

Для обчислення значення функції operator+() ми спершу додаємо значення feet та inches обох операндів (коректуючи результат при потребі). Одержані значення f та i використовуємо при ініціалізації безіменного об’єкту класу Distance, який використовуватиметься у виразі

return Distance (f,i);

Схожі методи можна створити в класі Distance для перезавантаження інших операцій. Тоді ми зможемо виконувати віднімання, множення і ділення з об’єктами цього класу, використовуючи звичайний запис виразів.

 

Об’єднання рядків

Операція «+» не може бути використана для об’єднання рядків. Тобто ми не можемо використати вираз типу

str3=str1+str2;

де str1, str2, str3 – рядкові змінні. Однак ми можемо сконструювати власний тип String і перезавантажити операцію «+» для об’єднання рядків (в С++ є стандартний тип «string», але ми створимо власний тип, щоб краще розібратися в механізмі перезавантаження). Приведемо лістінг програми 10.6.

#include <iostream.h>

#include <conio.h>

#include <bios.h>

#include <string.h>

#include <stdlib.h>

class String //клас для рядків

{private:

enum {SZ=80}; // max для рядків

char str[SZ]; //Масив для рядка

public:

String ()

{strcpy(str,””);}

 

String(char s[])

{strcpy(str,s);}

 

void display() const

{cout <<str;}

 

//operator

String operator+(String ss) const

{String temp;

if (strlen(str)+strlen(ss.str)<SZ)

{strcpy(temp.str,str);

strcat(temp.str,ss.str);

}

else

{cout <<”\nПереповнення!”;

exit(1);}

 

return temp;

}

};

//////////////////

int main()

{clrscr();

String s1=”\nЗ Новим Роком!”; //Конструктор з параметром

String s2=”З Різдвом!”;

String s3; //Конструктор без параметрів

//vyvid

s1.display();

s2.display();

s3.display();

 

s3=s1+s2;

s3.display();

cout <<endl;

bioskey(0);

return 0;

}

Програма 10.6

Спершу програма виводить на дисплей 3 різні рядки. Оскільки 3-ій рядок порожній, то не виводиться нічого. Далі два перші рядки об’єднуються в один рядок. Перезавантаження операції + схоже на те, що ми робили раніше. Оголошення

String operator+(String ss) const

показує, що функція operator+() приймає один аргумент типу String і повертає об’єкт цього ж типу. При об’єднанні рядків за допомогою функції operator+() створюється тимчасовий об’єкт типу String, в нього копіюється рядок об’єкту, для якого викликана функція. Потім, використовуючи бібліотечну функцію strcat(), ми приєднуємо до неї рядок з об’єкту аргументу і повертаємо одержаний у тимчасовому об’єкті рядок. Зауважимо, що ми не можемо використати

return String(string);

такий підхід, де створюється безіменний тимчасовий об’єкт типу String, оскільки нам потрібний доступ до тимчасового об’єкту не тільки для його ініціалізації, а й для приєднання до нього рядка аргументу. Щоб не допустити переповнення рядка, ми перевіряємо, чи не перевищує загальна довжина двох об’єднуваних рядків максимально допустиму. Якщо перевищує, то виводимо повідомлення про помилку замість виконання операції об’єднання.

 

 

Множинне перезавантаження

Ми розглянули різні приклади використання операції + для додавання інтервалів та об’єднання рядків. Можна використовувати обидва написані нами класи в одній програмі, при цьому компілятор знатиме, яка з функцій нам потрібна, оскільки він вибирає функцію, виходячи з операндів операції. Нагадаємо, що таке явище є проявом принципу поліморфізму.

 

Операції порівняння

Розглянемо перезавантаження операцій іншого типу, а саме операцій порівняння.

 



Поделиться:


Последнее изменение этой страницы: 2021-12-15; просмотров: 57; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.224.32.86 (0.011 с.)