简体   繁体   English

Java 的 equals() 和 C++ 的运算符 == 有什么区别?

[英]What is the difference between Java's equals() and C++'s operator ==?

In a question regarding the use of typeid is C++, I suggested it could be used to compare types in objects comparison.关于typeid使用的问题是 C++ 中,我建议它可以用于比较对象比较中的类型。 I haven't seen it done much, but I had Java's equals in mind.我没有看到它做太多,但我想到了 Java 的equals

Looking into Java a bit more , this seems to be the case: Some say the actual classes of the two objects should be compared, and some say instanceof is the right tool to use, possibly with double dispatch. 仔细研究 Java ,似乎是这样: 有人说应该比较两个对象的实际类, 有人说instanceof是正确的工具,可能使用双重调度。 There are of course cases in which one of the two is definitively more suitable, but at least both options are considered .当然,在某些情况下,两者中的一个肯定更合适,但至少两个选项都被考虑在内

In C++, OTOH, I could barely find code in which the actual types are compared.在 C++,OTOH 中,我几乎找不到比较实际类型的代码。 On most cases, double dispatch is used (with dynamic_cast ), and I couldn't find anyone insisting a quick type comparison is the right thing to do at the beginning of the equality check.在大多数情况下,使用双重分派(使用dynamic_cast ),我找不到任何人坚持快速类型比较是在相等检查开始时做的正确事情。

I'm wondering why the problem of polymorphic type comparison has two acceptable solutions in Java, while in C++ only one seems to be considered the best practice?我想知道为什么多态类型比较的问题在 Java 中有两个可接受的解决方案,而在 C++ 中似乎只有一个被认为是最佳实践? Are there significant technical differences, or just different approaches?是否存在显着的技术差异,或者只是不同的方法?

Note: My claims are based on impression, not concrete knowledge.注意:我的说法是基于印象,而不是具体知识。 If they are wrong and Java and C++ are indeed similar in that aspect - or different for reasons other than the above, it will obviously be an acceptable answer.如果它们是错误的,并且 Java 和 C++ 在这方面确实相似 - 或者由于上述以外的原因而有所不同,这显然是一个可以接受的答案。

In Java, all types ultimately derive from Object , and Object defines a virtual function Object.equals(Object other) , so you can compare anything with anything else, regardless of whether it makes sense or not. In Java, all types ultimately derive from Object , and Object defines a virtual function Object.equals(Object other) , so you can compare anything with anything else, regardless of whether it makes sense or not. In C++, there is no univeral base, and there is no implicit definition of == .在 C++ 中,没有通用基础,也没有==的隐式定义。 == is normally only overridden when it makes sense, for comparing objects of the same type, and the compiler will complain if you write nonsense code. ==通常仅在有意义时才被覆盖,用于比较相同类型的对象,如果您编写无意义的代码,编译器会抱怨。 In cases where there is an inheritance hierarchy, it is, of course, up to the author to decide whether == makes sense (I usually doesn't, but there are a lot of exceptions), and if so, what it should mean with respect to comparing objects of different types.在有 inheritance 层次结构的情况下,当然由作者来决定==是否有意义(我通常没有,但有很多例外),如果是,它应该意味着什么关于比较不同类型的对象。 Within the hierarchy, or outside of it: it might make sense to support == between BigInteger and BigFloat , for example, even if the classes aren't related by inheritance.在层次结构内部或外部:例如,在BigIntegerBigFloat之间支持==可能是有意义的,即使这些类与 inheritance 无关。

The reason you don't see the problem discussed much in C++ is, of course, because you don't define == unless there's some logical meaning for it, and then you define it according to the logical meaning.你没有看到C++中讨论的问题的原因当然是因为你不定义==除非它有一些逻辑含义,然后你根据逻辑含义定义它。 In Java, you generally have to define equals regardless, so you have to "invent" some meaning, and you get discussion over what the invented meaning should be.在 Java 中,您通常必须无论如何定义equals ,因此您必须“发明”一些含义,然后讨论发明的含义应该是什么。

An obvious difference is that Java equals is a virtual method (since all Java methods are by default), so will do dynamic dispatch based on its target.一个明显的区别是 Java equals是一个虚方法(因为所有 Java 方法都是默认的),所以会根据它的目标做动态调度。

C++ operator== overloads are statically resolved, but it's easy to delegate to a virtual function if you want polymorphic behavior. C++ operator==重载是静态解决的,但如果你想要多态行为,很容易委托给虚拟 function。

Except for the difference in polymorphism, all other behavior is completely up to the implementer of the particular type (or in the C++ case, the implementer of a freestanding operator== ).除了多态性的差异之外,所有其他行为完全取决于特定类型的实现者(或者在 C++ 的情况下,独立operator==的实现者)。

Java has a single base-type for all reference types -- all reference types extend java.lang.Object (modulo null which breaks equals symmetry since (null).equals(...) is an error). Java has a single base-type for all reference types -- all reference types extend java.lang.Object (modulo null which breaks equals symmetry since (null).equals(...) is an error).

So you can say in Java "do these two java references point to equivalent things?"所以你可以在 Java 中说“这两个 java 引用是否指向相同的东西?” without knowing anything about the types of the references, so Java has a place to hang an equals(Object) method of its base reference type, java.lang.Object in a way that C++ does not. without knowing anything about the types of the references, so Java has a place to hang an equals(Object) method of its base reference type, java.lang.Object in a way that C++ does not. In C++ there is no such base-type so you have a multitude of different == operator and the compiler has to be able to figure out statically which to use.在 C++ 中没有这样的基本类型,所以你有许多不同的==运算符,编译器必须能够静态地找出使用哪个。

Since Java objects always carry RTTI and all dispatch to an instance method is speced as virtual, there are things you can do with reflection when defining equivalence classes in code that you simply cannot with C++ objects.由于 Java 对象总是携带 RTTI 并且所有对实例方法的分派都指定为虚拟的,因此在代码中定义等价类时,您可以使用反射来做一些您无法使用 C++ 对象做的事情。

Making C++ == equivalent to Java's equals assumes that you've overridden the == operator to do "deep equals" in C++ and the Java "equals" to do the same.使 C++ == 等效于 Java 的 equals 假设您已经覆盖了 == 运算符以在 C++ 和 ZD52387880E1EA22817A72D37592138 中执行“深度等于”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM