¿Cuál es la forma correcta de sobrecargar el operador == para una jerarquía de clases?

Supongamos que tengo la siguiente jerarquía de clases:

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

A::~A() {}

class B : public A
{
    int bar;
};

class C : public A
{
    int baz;
};

¿Cuál es la forma correcta de sobrecargaroperator== para estas clases? Si hago todas las funciones gratuitas, B y C no pueden aprovechar la versión de A sin lanzar. También evitaría que alguien realice una comparación profunda con solo referencias a A. Si les hago funciones miembro virtuales, una versión derivada podría tener este aspecto:

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

Una vez más, todavía tengo que lanzar (y se siente mal). ¿Hay una forma preferida de hacer esto?

Actualizar:

Hasta el momento solo hay dos respuestas, pero parece que la forma correcta es análoga al operador de asignación:

Hacer clases abstractas sin hojas.Protegido no virtual en las clases no-hoja.Público no virtual en las clases hoja.

Cualquier intento de usuario de comparar dos objetos de diferentes tipos no se compilará porque la función base está protegida, y las clases de hoja pueden aprovechar la versión de los padres para comparar esa parte de los datos.

Respuestas a la pregunta(5)

Su respuesta a la pregunta