Classes and class hierarchies
C.87
Остерегайтесь `==` на базовых классах
Причина
Действительно сложно написать безопасное и полезное == для иерархии.
Пример, плохо
class B {
string name;
int number;
public:
virtual bool operator==(const B& a) const
{
return name == a.name && number == a.number;
}
// ...
};
== класса B принимает преобразования для второго операнда, но не для первого.
class D : public B {
char character;
public:
virtual bool operator==(const D& a) const
{
return B::operator==(a) && character == a.character;
}
// ...
};
B b = ...
D d = ...
b == d; // сравнивает name и number, игнорирует character из d
d == b; // сравнивает name и number, игнорирует character из d
D d2;
d == d2; // сравнивает name, number и character
B& b2 = d2;
b2 == d; // сравнивает name и number, игнорирует character из d2 и d
Конечно, есть способы заставить == работать в иерархии, но наивные подходы не масштабируются.
Примечание
Это правило применяется ко всем обычным операторам сравнения: !=, <, <=, >, >= и <=>.
Применение
- Отмечайте виртуальный
operator==(); то же самое для других операторов сравнения:!=,<,<=,>,>=и<=>.