ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ В C++ (4-Е ИЗДАНИЕ) (часть 8) онлайн
Арифметические операции
В программе ENGLCON из главы 6 мы рассматривали два объекта класса Distance, которые складывались с помощью метода add_dist();
dist3.add_dist ( dist1, dist2 );
Используя перегрузку операции +, мы можем отказаться от этого непригляд- ного выражения и воспользоваться таким:
dist 3 = dist1 + dist2;
В листинге программы ENGLPLUS реализована эта возможность:
// engplus.cpp
// перегрузка операции + для сложения переменных типа Distances
#include <iostream>
using namespace std;
///////////////////////////////////////////////////////////
class Distance // класс английских мер длины
{
private:
int feet;
float inches;
public:
// конструктор без параметров
Distance ( ) : feet ( 0 ), inches ( 0.0 )
{ }
// конструктор с двумя параметрами
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;
};
///////////////////////////////////////////////////////////
// сложение двух длин
Distance Distance::operator+ ( Distance d2 ) const
{
int f = feet + d2.feet; // складываем футы
float i = inches + d2.inches; // складываем дюймы
if ( i >= 12.0 ) // если дюймов стало больше 12
{
i -= 12.0; // то уменьшаем дюймы на 12
f++; // и увеличиваем футы на 1
}
return Distance ( f, i ); // создаем и возвращаем временную переменную
}
///////////////////////////////////////////////////////////
int main ( )
{
Distance dist1, dist3, dist4; // определяем переменные
dist1.getdist ( ); // получаем информацию
Distance dist2 ( 11, 6.25 ); // определяем переменную с конкретным значением
dist3 = dist1 + dist2; // складываем две переменные
dist4 = dist1 + dist2 + dist3; // складываем несколько переменных
// показываем, что же у нас получилось
cout << "dist1 = "; dist1.showdist ( ); cout << endl;
cout << "dist2 = "; dist2.showdist ( ); cout << endl;
cout << "dist3 = "; dist3.showdist ( ); cout << endl;
cout << "dist4 = "; dist4.showdist ( ); cout << endl;
return 0;
}
Для того чтобы показать, что результат сложения может быть использован в других операциях, мы выполнили в функции main() следующие действия: сло- жили dist1, dist2 и dist3, чтобы получить dist4 (значение которой представляет собой удвоенное значение переменной dist3), в строке:
dist4 = dist1 + dist2 + dist3;
Вот результат работы программы:
Введите футы: 10 Введите дюймы: 6.5
dist1 = 10'-6.5" - ввод пользователя
dist2 = 11'-6.25" - предопределено в программе
dist3 = 22'-0.75" - dist1+dist2
dist4 = 44'-1.5" - dist1+dist2+dist3
Объявление метода operator+() в классе Distance выглядит следующим образом: Distance operator+ ( Distance );
Эта операция возвращает значение типа Distance и принимает один аргумент типа Distance. В выражении:
dist3 = dist1 + dist2;
важно понимать, к каким объектам будут относиться аргументы и возвраща- емые значения. Когда компилятор встречает это выражение, то он просматри- вает типы аргументов. Обнаружив только аргументы типа Distance, он выполняет операции выражения, используя метод класса Distance operator+(). Но какой из объектов используется в качестве аргумента этой операции — dist1 или dist2? И не нужно ли нам использовать два аргумента, так как мы складываем два объекта?
Существует правило: объект, стоящий с левой стороны операции (в нашем случае dist1), вызывает функцию оператора. Объект, стоящий справа от знака операции, должен быть передан в функцию в качестве аргумента. Операция воз- вращает значение, которое мы затем используем для своих нужд. В нашем случае мы присваиваем его объекту dist3. Рисунок 8.2 иллюстрирует все эти действия.

Рис. 8.2. Перегрузка бинарной операции с одним аргументом
В функции operator+() к левому операнду мы имеем прямой доступ, исполь- зуя feet и inches, так как это объект, вызывающий функцию. К правому операн- ду мы имеем доступ как к аргументу функции, то есть как d2.feet и d2.inches.
Мы можем обобщить изложенное выше и сказать, что перегруженной опера- ции всегда требуется количество аргументов на один меньшее, чем количество операндов, так как один из операндов является объектом, вызывающим функ- цию. Поэтому для унарных операций не нужны аргументы (это правило не-
верно для функции и операторов, являющихся дружественными для класса. Мы обсудим имеющиеся возможности C++ в главе 11).
Для вычисления значения функции operator+() мы сначала складываем зна- чения feet и inches обоих операндов (корректируя результат, если это необходи- мо). Полученные значения f и i мы затем используем при инициализации безы- мянного объекта класса Distance, который затем будет возвращен в выражение.
return Distance ( f, i );
Это похоже на расположение, используемое в COUNTPP3, за исключением то- го, что конструктор принимает два аргумента вместо одного. В строке
dist3 = dist1 + dist2;
функции main() затем присваивается значение безымянного объекта класса Distance переменной dist3. Сравните это интуитивно-понятное выражение с ис- пользованием вызова функции для выполнения той же задачи, как это было сде- лано в программе ENGLCON из главы 6.
Похожие методы вы сможете создать в классе Distance для перегрузки других операций. Тогда вы сможете выполнять вычитание, умножение и деление с объ- ектами этого класса, используя обычную запись выражений.
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
Схожі підручники
- Міжнародні економічні зв’язки України та її інтеграція в європейські та інші світові структури
- Загальні питання з курсу Соціологія (частина 2)
- Філософія (частина 2)
- Сказка про Весельчака
- Методичні вказівки до виконання розрахункової роботи з дисципліни «Системи промислових технологій в галузях економіки»
- Історія економіки та економічної думки
