在a question regarding the use of typeid
中是C ++,我建议它可以用来比较对象比较中的类型。我没有看到它做得太多,但我记得Java equals
。
Looking into Java a bit more,情况似乎如此:Some say应比较两个对象的实际类,some say instanceof
是正确使用的工具,可能有双重调度。当然有两种情况中的一种最终更合适,但至少both options are considered。
在C ++,OTOH中,我几乎找不到比较实际类型的代码。在大多数情况下,使用双重调度(使用dynamic_cast
),我找不到任何坚持快速类型比较的人在同等检查开始时做正确的事情。
我想知道为什么多态类型比较的问题在Java中有两个可接受的解决方案,而在C ++中,只有一个似乎被认为是最佳实践?是否存在重大的技术差异,或者只是采用不同的方法?
注意:我的主张是基于印象而非具体知识。如果它们是错的并且Java和C ++在这方面确实相似 - 或者由于上述原因以外的原因而不同,那么它显然是一个可接受的答案。
答案 0 :(得分:7)
在Java中,所有类型最终都来自Object
和Object
定义一个虚函数Object.equals(Object other)
,所以你
可以比较任何东西,无论是否
它是否有意义。在C ++中,没有通用的基础,而且
没有==
的隐含定义。 ==
通常只是
在有意义的时候重写,用于比较对象
相同的类型,如果你写废话,编译器会抱怨
码。在存在继承层次结构的情况下,它是,
当然,由作者决定==
是否有意义
(我通常不会,但有很多例外),如果
所以,它在比较对象时应该是什么意思
不同种类。在层次结构内或其外部:它
在==
和BigInteger
之间支持BigFloat
可能有意义
例如,==
,即使这些类不相关
继承。
你没有看到C ++中讨论的问题的原因是,
当然,因为你没有定义equals
,除非有一些
它的逻辑意义,然后你根据它来定义它
逻辑意义。在Java中,您通常必须定义{{1}}
无论如何,所以你必须“发明”一些意义,你得到
讨论发明意义应该是什么。
答案 1 :(得分:2)
一个明显的区别是Java equals
是一个虚方法(因为所有Java方法都是默认方式),因此将根据其目标进行动态调度。
C ++ operator==
重载是静态解析的,但如果你想要多态行为,很容易委托给虚函数。
除了多态性的差异之外,所有其他行为完全取决于特定类型的实现者(或者在C ++案例中,是独立式operator==
的实现者)。
答案 2 :(得分:1)
Java对所有引用类型都有一个基类型 - 所有引用类型都扩展为java.lang.Object
(模null
,因为equals
是错误而导致(null).equals(...)
对称性中断
所以你可以在Java中说“这两个java引用是否指向相同的东西?”在不知道引用类型的任何内容的情况下,Java可以以C ++不支持的方式挂起其基本引用类型equals(Object)
的{{1}}方法。在C ++中没有这样的基类型,所以你有很多不同的java.lang.Object
运算符,编译器必须能够静态地找出使用哪个。
由于Java对象总是带有RTTI,并且所有对实例方法的调度都是虚拟的,因此在代码中定义等价类时,可以使用反射做些事情,而C ++对象则无法实现。
答案 3 :(得分:0)
使C ++ ==等同于Java的等于假设您已经重写了==运算符以在C ++中执行“deep equals”,并且Java“等于”执行相同操作。