Полиморфизм. Перегрузка операций

Отличительной особенностью С++ является способность перегрузки (переопределения) существующих операций. Встроенные операции, такие как +, являются изначально перегруженными даже в языке С.

Пример 18.

Перегрузка встроенной операции +.

void main ()

{ int i = 2, j = 3; k;

float a = 2.5, b = 1.3, c;

k = i + j;

c = a + b;

cout<< "k=" << k <<" c=" << c;

}

Результаты: k=5 c=3.8

Для операндов типа int и float используется одна и та же операция, но, оче­видно, что код генерируется разный, так как целые и вещественные числа пред­ставляются в памяти по разному. С++ просто расширяет эту идею, давая воз­можность переопределять операции на уровне пользователя.

За небольшим исключением большинству операций языка С++ может быть придано специальное значение относительно вновь определенных классов. Для встроенных типов данных значение операции изменить нельзя. Например, класс, который определяет список указателей, может использовать операцию + для добавления объекта в список.

Когда операция перегружена, ни одно из ее исходных значений не теряет­ся. Просто вводится новая операция относительно нового конкретного класса. Для этого создается специальная функция-операции, которая определяет дей­ствие этой операции согласно форме:

тип имя_класса :: operator # ( список аргументов)

{ // операторы, определяющие действие функции-операции

. . .

},

где тип – тип возвращаемого значения, # – конкретный знак операции.

Часто возвращаемое значение того же типа, что и класс, хотя возможен и другой тип этого значения. Функция-операции должна быть или элементом класса или дружественной функцией, при этом имеются небольшие отличия.

Пример 19.

Рассмотрим программу, в которой перегружаются операции: +, ++, --, = относительно класса Vector, который определяет трехмерный вектор в евклидо­вом пространстве с координатами x, y, z. Операция сложения двух векторов выполняется как сложение соответствующих координат.

#include<iostream.h>

#include<conio.h>

class Vector

{ int x, y, z; // координаты вектора

public:

Vector(int mx=0, int my=0, int mz=0); // конструктор с 3-мя параметрами

// по умолчанию

Vector operator + (Vector t); // функция-операция +

Vector operator = (Vector t); // функция-операция =

Vector operator ++ (); // функция-операция ++

Vector operator - - (); // функция-операция - -

void show(void); // функция вывода координат

};

Vector::Vector(int mx, int my, int mz) // конструктор с 3-мя параметрами

{ x=mx; y=my; z=mz; // инициализация 3-х координат

}

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

Vector Vector::operator + (Vector t) // использование указателя this

{ Vector temp;

temp.x = x + t.x; // temp.x = this->x + t.x; и т. д.

temp.y = y + t.y;

temp.z = z + t.z;

return temp;

}

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

Vector Vector::operator = (Vector t) // использование указателя this

{ x = t.x; // this->x = t.x; и т. д.

y = t.y;

z = t.z;

return *this; // возврат указателя this

}

// Перегрузка операции ++ (унарной префиксной и постфиксной одинаково)

Vector Vector::operator ++ ()

{

x++; y++; z++; // увеличение координат на 1

return *this; // возврат указателя this

}

// Перегрузка операции -- (унарной префиксной и постфиксной одинаково)

Vector Vector::operator -- ()

{

x--; y--; z--; // уменьшение координат на 1

return *this; // возврат указателя this

}

void Vector::show(void) // функция вывода 3-х координат

{

cout <<" x=" << x << " y=" << y << " z=" << z << '\n';

}

void main() // главная функция

{ clrscr(); // чистка экрана

Vector a(3, 2, 1), b(10, 20, 30), c; // три объекта с инициализацией

cout<<"вектор исходный а: "; a.show(); // вывод вектора а

cout<<"вектор исходный b: "; b.show(); // вывод вектора b

c=a + b; // перегруженный оператор +

cout<<"вектор c=a+b: "; c.show(); // вывод вектора с

c=a+b+c; // перегруженный оператор +

cout<<"вектор c=a+b+c: "; c.show(); // вывод вектора с

c = b = a; // перегруженный оператор =

cout<<"вектор c=b=a: "; c.show(); // вывод вектора с

++b; // перегруженный оператор ++

cout<<"вектор ++b: "; b.show(); // вывод вектора b

b- -; // перегруженный оператор --

cout<<"вектор b- -: "; b.show(); // вывод вектора b

getch();

}

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

вектор исходный а: x=3, y=2, z=1

вектор исходный b: x=10, y=20, z=30

вектор c=a+b: x=13, y=22, z=31

вектор c=a+b+c: x=26, y=44, z=62

вектор c=b=a: x=3, y=2, z=1

вектор ++b: x=4, y=3, z=3

вектор b- -: x=3, y=2, z=1

Комментарии к программе.

Как видно, функция-операции имеет только один параметр, когда сами функции определяют бинарные операции (+, =). Первый операнд использует this-указатель, а второй – передается как параметр функции.

Если используются методы, то не нужны параметры для унарных опера­ций и требуется лишь один параметр для бинарных операций. Объект, активи­зирующий операцию, передается в функцию-операцию неявно через указатель this.

В этом примере важно то, что возвращаемое значение имеет тип vector, что позволяет использовать выражение вида a+b+c. Перегруженная операция + не изменяет значения своих операндов, а перегруженная операция = модифици­рует операнд слева.

Наши рекомендации