2011-07-20 23 views
10

En a question regarding the use of typeid es C++, sugerí que podría usarse para comparar tipos en comparación de objetos. No lo he visto hecho mucho, pero tenía en mente el equals de Java.¿Cuál es la diferencia entre los iguales de Java() y el operador de C++ ==?

Looking into Java a bit more, este parece ser el caso: Some say las clases reales de los dos objetos se deben comparar, y some sayinstanceof es la herramienta adecuada para usar, posiblemente con el doble de despacho. Por supuesto, hay casos en los que uno de los dos es definitivamente más adecuado, pero al menos both options are considered.

En C++, OTOH, apenas podía encontrar el código en el que se comparan los tipos reales. En la mayoría de los casos, se utiliza el doble despacho (con dynamic_cast), y no pude encontrar a nadie insistiendo en que una comparación de tipo rápido sea lo correcto al comienzo de la verificación de igualdad.

Me pregunto por qué el problema de la comparación de tipo polimórfico tiene dos soluciones aceptables en Java, mientras que en C++, solo una parece ser considerada la mejor práctica. ¿Existen diferencias técnicas significativas, o solo enfoques diferentes?

Nota: Mis afirmaciones se basan en la impresión, conocimiento no concreto. Si están equivocados y Java y C++ son realmente similares en ese aspecto, o diferentes por razones distintas a las anteriores, obviamente será una respuesta aceptable.

+0

En C++ '==' puede estar sobrecargado, por lo que depende del contexto ... – Schnommus

+2

@Schnommus: En Java, 'equals' puede anularse. No hay mucha diferencia allí. –

+1

@Ben Voigt: Buen punto. Eliminaría mi comentario si no fuera por el bien del lector – Schnommus

Respuesta

7

En Java, todos los tipos, en última instancia derivan de Object y Object define una función virtual Object.equals(Object other), por lo que puede comparar cualquier cosa con cualquier otra cosa, independientemente de si tiene sentido o no.En C++, no hay una base univeral, y no hay una definición implícita de ==. == normalmente solo está anulado cuando tiene sentido, para comparar objetos del mismo tipo , y el compilador se quejará si escribe el código sin sentido. En los casos donde hay una jerarquía de herencia, es, por supuesto, hasta el autor para decidir si == tiene sentido (normalmente no, pero hay muchas excepciones), y si entonces, qué debe significar con respecto a la comparación de objetos de diferentes tipos. Dentro de la jerarquía, o fuera de ella: puede tener sentido para admitir == entre BigInteger y BigFloat, por ejemplo, incluso si las clases no están relacionadas por herencia .

La razón por la que no se ve el problema discutido mucho en C++ es, por supuesto, porque no se define == menos que haya algún significado lógico para él, y luego se definen de acuerdo con el significado lógico . En Java, generalmente tiene que definir equals independientemente, por lo que tiene que "inventar" algún significado, y obtiene discusión sobre cuál debe ser el significado inventado.

0

Hacer C++ == equivalente a los iguales de Java supone que ha anulado el operador == para hacer "profundos iguales" en C++ y que Java "es igual" para hacer lo mismo.

+0

Como dije, tienes que anular iguales para hacer iguales profundos. Ver Joshua Bloch "Effective Java" capítulo 3. – duffymo

+0

bastante justo. Borrando mi comentario original. –

2

Una diferencia obvia es que Java equals es un método virtual (ya que todos los métodos de Java son por defecto), por lo que hará un despacho dinámico basado en su objetivo.

Las sobrecargas de C++ operator== están resueltas estáticamente, pero es fácil delegar en una función virtual si desea un comportamiento polimórfico.

Excepto por la diferencia en polimorfismo, todos los demás comportamientos dependen por completo del implementador del tipo particular (o en el caso C++, el implementador de un operator== autónomo).

1

Java tiene un solo tipo de base para todos los tipos de referencia - todos los tipos de referencia se extienden java.lang.Object (módulo null que rompe equals simetría desde (null).equals(...) es un error).

Así que puedes decir en Java "¿estas dos referencias de Java apuntan a cosas equivalentes?" sin saber nada sobre los tipos de las referencias, por lo que Java tiene un lugar para colgar un método equals(Object) de su tipo de referencia base, java.lang.Object de una manera que C++ no lo hace. En C++ no existe tal tipo de base por lo que tiene una multitud de operadores diferentes de == y el compilador debe poder determinar de forma estática cuál usar.

Dado que los objetos Java siempre llevan RTTI y todo el despacho a un método de instancia se expresa como virtual, hay cosas que puede hacer con la reflexión al definir clases de equivalencia en código que simplemente no puede con objetos C++.

+1

Java '==' parece estar fuera de tema para esta pregunta. –

+0

@Ben, de acuerdo. Editaré –

Cuestiones relacionadas