Перегрузка операторов крайне удобная возможность языка С++. Ведь можем написать:
#include <iostream>
class Point2i
{
int x;
int y;
public:
Point2i(int x, int y):x(x),y(y){}
bool operator==(const Point2i & other)
{
return x == other.x && y == other.y ? true:false;
}
};
int main() {
Point2i p1(12, 3);
Point2i p2(1, -11);
if(p1 == p2)
std::cout<<"p1==p2"<<'\n';
return 0;
}
Скорее всего бывают случаи когда это не уместно.
Когда перегрузка операторов это плохо?
P.S Имеется в виду о любых операторах
В качестве эпиграфа:
— Нужно потреблять, но не злоупотреблять, — поучительным тоном заметил Арамис.
А. Дюма, "Три мушкетера"
Это очень плохо, когда нарушается семантика (попросту, смысл) оператора.
Например, возьмем ваши точки. Что такое их вычитание или умножение? (если это точки, а не двумерные вектора). Или что такое отношение < для точек? хотя никто не мешает вам написать, например, сравнение модулей расстояний от начала координат. Или еще чего - но это будет неочевидное сравнение. А ведь можно написать оператор <, который будет, скажем, выводить суммы всех четырех координат :)
Или, например, то же отношение равенства, как вы написали, но которое возвращает не bool, а считает, скажем, какую-то строку - пусть те же "true" и "false".
Такое применение запутывает всех читающих код, в том числе самого автора.
Есть еще хитрые случаи, связанные с поиском имен, но это уже достаточно большая редкость.
А главное - смотри эпиграф. Ничто не следует использовать только по той причине, что его можно использовать. Вы никогда не видели "картин", которые создают малолетки, научившиеся какой-то возможности в фотошопе, и использующие ее только потому, что "вот как я умею!" (кстати, грешат этим и взрослые, особенно в кино...)? Или тексты, изобилующие одновременно 20 шрифтами? :) Вот просто не делайте такие программы, и все будет хорошо :)
P.S. Кстати, не забывайте, что ассоциативность и приоритеты операторов сохраняются, так что сделать, скажем, оператор ^ оператором возведения в степень оказывается, гм... не очень умной идеей.
Конкретный пример языковой неконсистентности, потенциально приводящий к эпическим фейлам. В С++ для встроенных логических операторов вычисление правого операнда не производится, если после вычисления значения левого операнда результат операции определен. Например в Is_Good() && Do_Work() функция Do_Work не будет вызвана, если Is_Good возвращает false. Однако для перегруженных логических операторов это не соблюдается! Кроме того, операнды перегруженного логического оператора могут вычисляться вообще в любом порядке, так что в этом примере при использовании tribool функция Do_Work внезапно вызывается даже до Is_Good:
#include <boost/logic/tribool.hpp>
#include <boost/logic/tribool_io.hpp>
#include <iostream>
template<typename x_Bool> class t_Fancy
{
private: x_Bool Is_Good(void) const
{
::std::cout << "is not good!" << ::std::endl;
return false;
}
// must be called only when Is_Good returns true!
private: x_Bool Do_Work(void) const
{
::std::cout << "FAIL" << ::std::endl;
return false;
}
public: x_Bool Work(void) const
{
return Is_Good() && Do_Work();
}
};
int main()
{
::std::cout << ::std::boolalpha << t_Fancy<bool>{}.Work() << ::std::endl;
::std::cout << ::std::boolalpha << t_Fancy<::boost::tribool>{}.Work() << ::std::endl;
return 0;
}
online compiler
is not good!
false
FAIL
is not good!
false
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости