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

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

本文关键字:什么 区别 运算符 C++ equals Java      更新时间:2023-10-16

在一个关于使用typeid是c++的问题中,我建议它可以用于对象比较中的类型比较。我没有看到它做得很多,但我有Java的equals在脑海中。

再深入研究一下Java,情况似乎就是这样:有些人说应该比较两个对象的实际类,有些人说instanceof是使用的正确工具,可能带有双重分派。当然,在某些情况下,两种选择中的一种肯定更合适,但至少两种选择都要考虑。

在c++中,OTOH,我几乎找不到比较实际类型的代码。在大多数情况下,使用双调度(dynamic_cast),我找不到任何人坚持认为在相等性检查的开始进行快速类型比较是正确的事情。

我想知道为什么多态类型比较的问题在Java中有两个可接受的解决方案,而在c++中只有一个似乎被认为是最佳实践?是否存在重大的技术差异,或者只是方法不同?

注:我的说法是基于印象,不是具体的知识。如果他们错了,而Java和c++在这方面确实相似——或者由于上述原因而有所不同,那么它显然是一个可以接受的答案。

在Java中,所有类型最终都派生自ObjectObject定义了一个虚函数Object.equals(Object other),因此可以将任何事物与其他事物进行比较,无论是否它是否有意义。在c++中,没有通用的基没有==的隐式定义。==通常为only的对象进行比较时,在有意义时重写相同的类型,如果你写了无意义的东西,编译器会报错代码。在存在继承层次结构的情况下,当然,==是否有意义取决于作者(我通常不这样做,但也有很多例外),如果那么,它对于比较物体的意义是什么呢不同的类型。在等级制度之内,或者在等级制度之外:它在BigInteger和之间支持==可能有意义例如,BigFloat,即使这些类没有关联继承。

在c++中很少讨论这个问题的原因是,当然,因为你不定义==,除非有一些它的逻辑意义,然后你根据逻辑意义。在Java中,通常必须定义equals不管怎样,所以你必须"发明"一些意义,你得到关于发明意义的讨论

一个明显的区别是Java equals是一个虚拟方法(因为所有Java方法都是默认的),因此将根据其目标进行动态分派。

c++ operator==重载是静态解析的,但是如果你想要多态行为,很容易委托给虚函数。

除了多态性的差异,所有其他行为完全取决于特定类型的实现者(或者在c++的情况下,独立operator==的实现者)。

Java对所有引用类型都有一个基本类型——所有引用类型都扩展java.lang.Object(对null取模,因为(null).equals(...)是错误的,因此打破了equals的对称性)。

所以你可以在Java中说"这两个Java引用指向相同的东西吗?"而不知道引用的类型,所以Java有一个地方挂起一个equals(Object)方法的基本引用类型,java.lang.Object,而c++没有。在c++中没有这样的基本类型,所以你有许多不同的==运算符,编译器必须能够静态地找出使用哪一个。

由于Java对象总是携带RTTI,并且对实例方法的所有分派都指定为虚的,因此在代码中定义等价类时,可以使用反射做一些事情,而这些事情在c++对象中是无法做到的。

使c++ ==等价于Java的等号,假设您已经覆盖了==操作符来实现c++中的"深度等号",并且Java中的"等号"也实现了同样的功能。