Jaki jest właściwy sposób przeciążenia operatora == dla hierarchii klas?
Załóżmy, że mam następującą hierarchię klas:
class A
{
int foo;
virtual ~A() = 0;
};
A::~A() {}
class B : public A
{
int bar;
};
class C : public A
{
int baz;
};
Jaki jest właściwy sposób przeciążeniaoperator==
dla tych klas? Jeśli zrobię z nich wszystkie wolne funkcje, to B i C nie mogą wykorzystać wersji A bez rzucania. Uniemożliwiłoby to również komuś dokonanie głębokiego porównania z odniesieniami tylko do A. Jeśli zrobię z nich wirtualne funkcje składowe, wtedy wersja pochodna może wyglądać tak:
bool B::operator==(const A& rhs) const
{
const B* ptr = dynamic_cast<const B*>(&rhs);
if (ptr != 0) {
return (bar == ptr->bar) && (A::operator==(*this, rhs));
}
else {
return false;
}
}
Ponownie wciąż muszę rzucać (i czuję się źle). Czy istnieje preferowany sposób, aby to zrobić?
Aktualizacja:
Jak dotąd są tylko dwie odpowiedzi, ale wygląda na to, że właściwy sposób jest analogiczny do operatora przypisania:
Uczyń abstrakcyjne klasy bez liściChronione nie-wirtualne w klasach innych niż liśćPubliczne nie wirtualne w klasach liściKażda próba porównania dwóch obiektów różnych typów przez użytkownika nie zostanie skompilowana, ponieważ funkcja bazowa jest chroniona, a klasy liści mogą wykorzystać wersję rodzica do porównania tej części danych.