Was ist der richtige Weg, um den Operator == für eine Klassenhierarchie zu überladen?

Angenommen, ich habe die folgende Klassenhierarchie:

class A
{
    int foo;
    virtual ~A() = 0;
};

A::~A() {}

class B : public A
{
    int bar;
};

class C : public A
{
    int baz;
};

Was ist der richtige Weg, um zu überlastenoperator== für diese Klassen? Wenn ich sie alle zu freien Funktionen mache, können B und C die Version von A nicht ohne Casting nutzen. Es würde auch jemanden daran hindern, einen tiefen Vergleich mit nur Verweisen auf A durchzuführen. Wenn ich sie zu virtuellen Member-Funktionen mache, könnte eine abgeleitete Version so aussehen:

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;
    }
}

Auch hier muss ich noch besetzen (und es fühlt sich falsch an). Gibt es einen bevorzugten Weg, dies zu tun?

Aktualisieren:

Bisher gibt es nur zwei Antworten, aber es sieht so aus, als wäre der richtige Weg analog zum Zuweisungsoperator:

Machen Sie Klassen, die keine Blätter sind, abstraktGeschützt, nicht virtuell in den Non-Leaf-KlassenÖffentlich, nicht virtuell in den Blattklassen

Jeder Benutzer, der versucht, zwei Objekte unterschiedlichen Typs zu vergleichen, wird nicht kompiliert, da die Basisfunktion geschützt ist und die Blattklassen die übergeordnete Version nutzen können, um diesen Teil der Daten zu vergleichen.

Antworten auf die Frage(5)

Ihre Antwort auf die Frage