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ści

Każ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.

questionAnswers(5)

yourAnswerToTheQuestion