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

{

 three_d temp = *this; // сохранение исходного значения

 х++; // инкремент координат х, у и z

 у++;

 z++;

 return temp; // возврат исходного значения

}

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

void three_d::show()

{

 cout << x << ", ";

 cout << у << ", ";

 cout << z << "\n";

}

int main()

{

 three_d a(1, 2, 3), b(10, 10, 10), c;

 a.show();

 b.show();

 с = a + b; // сложение объектов а и b

 c.show();

 c=a+b+c; // сложение объектов a, b и с

 с.show();

 с = b = a; // множественное присваивание

 с.show();

 b.show();

 ++c; // префиксная форма инкремента

 c.show();

 с++; // постфиксная форма инкремента

 с.show();

 а = ++с; // Объект а получает значение объекта с после его инкрементирования.

 a.show(); // Теперь объекты а и с

 с.show(); // имеют одинаковые значения.

 а = с++; // Объект а получает значение объекта с до его инкрементирования.

 a.show(); // Теперь объекты а и с

 с.show(); // имеют различные значения.

 return 0;

}

Вот как выглядят результаты выполнения этой версии программы.

1, 2, 3

10, 10, 10

11, 12, 13

22, 24, 26

1, 2, 3

1, 2, 3

2, 3, 4

3, 4, 5

4, 5, 6

4, 5, 6

4, 5, б

5, 6, 7

Как подтверждают последние четыре строки результатов программы, при префиксном инкрементировании значение объекта c увеличивается до выполнения присваивания объекту a, при постфиксном инкрементировании — после присваивания.

Помните, что если символ "++" стоит перед операндом, вызывается операторная функция operator++(), а если после операнда — операторная функция operator++(int notused).Тот же подход используется и для перегрузки префиксной и постфиксной форм оператора декремента для любого класса. В качестве упражнения определите оператор декремента для класса three_d.

Важно! Ранние версии языка C++ не содержали различий между префиксной и постфиксной формами операторов инкремента и декремента. Тогда в обоих случаях вызывалась префиксная форма операторной функции. Это следует иметь в виду, если вам придется работать со старыми С++-программами.

Советы по реализации перегрузки операторов

Действие перегруженного оператора применительно к классу, для которого он определяется, не обязательно должно иметь отношение к стандартному действию этого оператора применительно к встроенным С++-типам. Например, операторы "<<" и ">>", применяемые к объектам cout и cin, имеют мало общего с аналогичными операторами, применяемыми к значениям целочисленного типа. Но для улучшения структурированности и читабельности программного кода создаваемый перегруженный оператор должен по возможности отражать исходное назначение того или иного оператора. Например, оператор "+", перегруженный для класса three_d, концептуально подобен оператору "+", определенному для целочисленных типов. Ведь вряд ли есть логика в определении для класса, например, оператора "+", который по своему действию больше напоминает оператор деления (/). Таким образом, основная идея создания перегруженного оператора — наделить его новыми (нужными для вас) возможностями, которые, тем не менее, связаны с его первоначальным назначением.

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