Предположим, у меня есть следующая иерархия классов:
Код: Выделить всё
class A
{
int foo;
virtual ~A() = 0;
};
A::~A() {}
class B : public A
{
int bar;
};
class C : public A
{
int baz;
};
Как правильно перегрузить оператор == для этих классов? Если я сделаю все эти функции свободными, то B и C не смогут использовать версию A без приведения. Это также помешает кому-либо выполнить глубокое сравнение, имея только ссылки на A. Если я сделаю их виртуальными функциями-членами, то производная версия может выглядеть так:
Код: Выделить всё
bool B::operator==(const A& rhs) const
{
const B* ptr = dynamic_cast(&rhs);
if (ptr != 0) {
return (bar == ptr->bar) && (A::operator==(*this, rhs));
}
else {
return false;
}
}
Опять же, мне все еще приходится кастовать (и это кажется неправильным). Есть ли предпочтительный способ сделать это?
Обновление:
Есть пока только два ответа, но похоже, что правильный путь аналогичен оператору присваивания:
- Сделать неконечные классы абстрактными
Сделать неконечные классы абстрактными
li>
Защищенный невиртуальный в нелистовых классах
- Публичный невиртуальный в конечных классах
Любая попытка пользователя сравнить два объекта разных типов не будет скомпилирована, поскольку базовая функция защищена, а конечные классы могут использовать родительскую версию для сравнения этой части данных.
Подробнее здесь:
https://stackoverflow.com/questions/169 ... -hierarchy