Выбрать главу

Глава 13: Перегрузка операторов

В C++ операторы можно перегружать для "классовых" типов, определяемых программистом. Принципиальный выигрыш от перегрузки операторов состоит в том, что она позволяет органично интегрировать новые типы данных в среду программирования.

Перегружая оператор, можно определить его значение для конкретного класса. Например, класс, который определяет связный список, может использовать оператор "+" для добавления объекта к списку. Класс, которые реализует стек, может использовать оператор "+" для записи объекта в стек. В каком-нибудь другом классе тот же оператор "+" мог бы служить для совершенно иной цели. При перегрузке оператора ни одно из оригинальных его значений не теряется. Перегруженный оператор (в своем новом качестве) работает как совершенно новый оператор. Поэтому перегрузка оператора "+" для обработки, например, связного списка не приведет к изменению его функции (т.е. операции сложения) по отношению к целочисленным значениям.

Перегрузка операторов тесно связана с перегрузкой функций. Чтобы перегрузить оператор, необходимо определить значение новой операции для класса, к которому она будет применяться. Для этого создается функция operator (операторная функция), которая определяет действие этого оператора. Общий формат функции operator таков.

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

{

 операция_над_классом

}

Операторы перегружаются с помощью функции operator.

Здесь перегружаемый оператор обозначается символом "#", а элемент тип представляет собой тип значения, возвращаемого заданной операцией. И хотя он в принципе может быть любым, тип значения, возвращаемого функцией operator, часто совпадает с именем класса, для которого перегружается данный оператор. Такая корреляция облегчает использование перегруженного оператора в составных выражениях. Как будет показано ниже, конкретное значение элемента список_аргументов определяется несколькими факторами.

Операторная функция может быть членом класса или не быть им. Операторные функции, не являющиеся членами класса, часто определяются как его "друзья". Операторные функции-члены и функции-не члены класса различаются по форме перегрузке. Каждый из вариантов мы рассмотрим в отдельности.

Перегрузка операторов с использованием функций-членов

Начнем с простого примера. В следующей программе создается класс three_d, который поддерживает координаты объекта в трехмерном пространстве. Для класса three_d перегружаются операторы "+" и "=". Итак, рассмотрим внимательно код этой программы.

// Перегрузка операторов с помощью функций-членов.

#include <iostream>

using namespace std;

class three_d {

  int x, y, z; // 3-мерные координаты

 public:

  three_d() { x = у = z = 0; }

  three_d(int i, int j, int k) {x = i; у = j; z = k; }

  three_d operator+(three_d op2); // Операнд op1 передается неявно.

  three_d operator=(three_d op2); // Операнд op1 передается неявно.

  void show();

};

// Перегрузка оператора "+".

three_d three_d::operator+(three_d op2)

{

 three_d temp;

 temp.x = x + op2.x; // Операции сложения целочисленных

 temp.у = у + ор2.у; // значений сохраняют оригинальный

 temp.z = z + op2.z; // смысл.

 return temp;

}

// Перегрузка оператора присваивания.

three_d three_d::operator=(three_d op2)

{

 x = op2.x; // Операции присваивания целочисленных

 у = ор2.у; // значений сохраняют оригинальный

 z = op2.z; // смысл.

 return *this;

}

// Отображение координат X, Y, Z.

void three_d::show()

{

 cout << x << ", ";