如何区分Java和C ++中的对象?或者根本没有区分它们?
以这些为例:
的 C ++
std::set<A> aset;
A a(1, 2); // Assume A has only two elements, and this constructor sets them both
aset.insert(a);
A a2(1, 2); // This would initialise a `A' object to the same values as `a', but a different object
aset.count(a2); // Would this return 1 or 0?
爪哇
set<A> aset;
A a = new A(1, 2); // Assume A has only two elements, and this constructor sets them both
aset.add(a);
A a2 = new A(1, 2); // This would initialise a `A' object to the same values as `a', but a different object
aset.contains(a2); // Would this return true or false?
答案 0 :(得分:7)
在C ++中,集合取决于为类A定义的运算符&lt;(),或者您为集合提供strict weak ordering的比较对象。
答案 1 :(得分:4)
对于Java
,它取决于equals, hashcode
合同。
答案 2 :(得分:1)
对于Java部分, 负责确定两个对象是否相等的方法是:
public boolean equals(Object other)
不要与
混淆public int hashCode()
谁的合同声明两个等于对象必须返回相同的数字,但返回相同数字的两个对象可能是,但不一定相等。
equals方法的默认实现是内存地址相等,因此如果A类没有覆盖equals方法,则contains方法将返回false。
要使set.contains(a2)方法返回true,必须覆盖equals和hashCode方法以符合:
public boolean equals(Object other) {
return other instanceof A && ((A) other).elem1 = this.elem1 && ((A) other).elem2 = this.elem2;
}
public int hashCode() {
return elem1 * 31 + elem2;
}
该集合需要hashCode(假设您正在使用HashSet)来识别对象的内部表示中的位置(即在哪里查找)。 如果您感兴趣,请搜索HashSet \ HashMap以了解内部表示。
至于C ++部分,如果我没记错的话,它取决于正确的运算符重载,但我的C ++充其量生锈。
编辑:我注意到你特意询问了套装,所以我会详细说明如何: 虽然equals方法决定了两个对象之间的相等性,但是所使用的set实现中的一些初步步骤(例如HashSet或TreeSet)可能会在一些额外的东西上传递:
例如,HashSet使用hashCode()函数来查找项可能位于的内部位置,因此如果A没有覆盖/正确实现hashCode()函数,则set.contains(a2)可能返回true或者为假(对于默认实现,它是非确定性的 - 取决于内存位置和集合的当前容量)。
要使TreeSet内部实现正确查找其中的项,要么包含的项必须正确实现Comparable接口,要么必须为TreeSet本身提供正确实现的Comparator实例。
答案 3 :(得分:0)
至少在Java中,对哈希码进行了比较,哈希码默认是从内存中对象的位置创建的。因此,在问题的Java部分,aset.contains(a2);
将返回false,因为a2
指向内存的不同部分a
。
我恐怕无法评论C ++是如何工作的!
答案 4 :(得分:0)
for C ++,根据C ++参考中的set :: insert
因为set容器不允许重复值,所以 插入操作检查每个 元素插入是否另一个 元素已存在于 具有相同值的容器,如果是这样, 元素未插入且-if 该函数返回一个值-a 返回它的迭代器
他们检查值,不像Java,它只检查地址。
答案 5 :(得分:0)
Java调用对象的equals
方法,如果你没有覆盖它,则与调用Object.hashCode()
相同。