Supongamos que tengo la siguiente jerarquía de clases:¿Cuál es la forma correcta de sobrecargar el operador == para una 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 sobrecargar operator==
para estas clases? Si hago todas las funciones gratuitas, entonces B y C no pueden aprovechar la versión de A sin conversión. También evitaría que alguien haga una comparación profunda que tiene sólo referencias a A. Si las hago funciones miembro virtuales, a continuación, 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 a emitir (y se siente mal). ¿Hay una manera preferida de hacer esto?
Actualización:
Sólo hay dos respuestas hasta el momento, pero se ve como la manera correcta es análogo al operador de asignación:
- hacer que las clases que no son hojas abstractas
- Protegidas no virtual en las clases que no son hojas
- Público no virtual en las clases de hojas
Cualquier intento de un usuario para comparar dos objetos de diferentes tipos no se compilará porque la función base está protegida, y las clases de hojas pueden aprovechar la versión de los padres para comparar esa parte de los datos.
Este es un problema clásico de despacho doble. Puede ser que su jerarquía se conoce de antemano, en cuyo caso debe escribir n * (n - 1) (. Por ejemplo devolver un hash del objeto y comparar los valores hash)/2 funciones, o no lo es y tiene que encontrar otra manera. –