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 << ", ";
cout << у << ", ";
cout << z << "\n";
}
int main()
{
three_d a(1, 2, 3), b(10, 10, 10), c;
a.show();
b.show();
c=a+b; // сложение объектов а и b
c.show();
c=a+b+c; // сложение объектов a, b и с
с.show();
c=b=a; // демонстрация множественного присваивания
с.show();
b.show();
return 0;
}
При выполнении эта программа генерирует такие результаты.
1, 2, 3
10, 10, 10
11, 12, 13
22, 24, 26
1, 2, 3
1, 2, 3
Исследуя код этой программы, вы, вероятно, удавились, увидев, что обе операторные функции имеют только по одному параметру, несмотря на то, что они перегружают бинарные операции. Это, на первый взгляд, "вопиющее" противоречие можно легко объяснить. Дело в том, что при перегрузке бинарного оператора с использованием функции-члена ей передается явным образом только один аргумент. Второй же неявно передается через указатель this
. Таким образом, в строке
temp.x = х + ор2.х;
под членом х
подразумевается член this->x, т.е. член х связывается с объектом, который вызывает данную операторную функцию. Во всех случаях неявно передается объект, указываемый слева от символа операции, который стал причиной вызова операторной функции. Объект, располагаемый с правой стороны от символа операции, передается этой функции в качестве аргумента. В общем случае при использовании функции-члена для перегрузки унарного оператора параметры не используются вообще, а для перегрузки бинарного — только один параметр. (Тернарный оператор "?" перегружать нельзя.) В любом случае объект, который вызывает операторную функцию, неявно передается через указатель this.Чтобы понять, как работает механизм перегрузки операторов, рассмотрим внимательно предыдущую программу, начиная с перегруженного оператора "+"
. При обработке двух объектов типа three_d оператором "+" выполняется сложение значений соответствующих координат, как показано в функции operator+(). Но заметьте, что эта функция не модифицирует значение ни одного операнда. В качестве результата операции эта функция возвращает объект типа three_d, который содержит результаты попарного сложения координат двух объектов. Чтобы понять, почему операция "+" не изменяет содержимое ни одного из объектов-участников, рассмотрим стандартную арифметическую операцию сложения, примененную, например, к числам 10 и 12. Результат операции 10+12 равен 22, но при его получении ни 10, ни 12 не были изменены. Хотя не существует правила, которое бы не позволяло перегруженному оператору изменять значение одного из его операндов, все же лучше, чтобы он не противоречил общепринятым нормам и оставался в согласии со своим оригинальным назначением.Обратите внимание на то, что функция operator+()
возвращает объект типа three_d. Несмотря на то что она могла бы возвращать значение любого допустимого в C++ типа, тот факт, что она возвращает объект типа three_d, позволяет использовать оператор "+" в таких составных выражениях, как a+b+с. Часть этого выражения, а+Ь, генерирует результат типа three_d, который затем суммируется с объектом с. И если бы эта часть выражения генерировала значение иного типа (а не типа three_d), такое составное выражение попросту не работало бы.