В чем разница между Java equals () и оператором C ++ ==? - PullRequest
10 голосов
/ 20 июля 2011

В вопрос об использовании typeid - это C ++, я предложил использовать его для сравнения типов при сравнении объектов.Я не видел, чтобы это было сделано много, но я имел в виду Java equals.

Если взглянуть на Java чуть более , похоже, это так: Некоторые говорят, фактические классы двух объектов должны сравниваться, и некоторые говорят, что instanceof - правильный инструмент для использования, возможно, с двойной диспетчеризацией.Конечно, есть случаи, когда один из двух определенно более подходит, но по крайней мере оба варианта считаются .

В C ++, OTOH, я едва мог найти код, в котором действительныйтипы сравниваются.В большинстве случаев используется двойная диспетчеризация (с dynamic_cast), и я не смог найти никого, кто бы настаивал на том, чтобы быстрое сравнение типов было правильным в начале проверки на равенство.

ЯИнтересно, почему проблема сравнения полиморфных типов имеет два приемлемых решения в Java, в то время как в C ++ только одно кажется наилучшим?Существуют ли значительные технические различия или просто разные подходы?

Примечание. Мои претензии основаны на впечатлениях, а не на конкретных знаниях.Если они ошибочны, а Java и C ++ действительно похожи в этом аспекте - или отличаются по причинам, отличным от указанных выше, это, очевидно, будет приемлемым ответом.

Ответы [ 4 ]

7 голосов
/ 21 июля 2011

В Java все типы в конечном итоге происходят от Object и Object определяет виртуальную функцию Object.equals(Object other), поэтому вы можно сравнить что угодно с чем угодно, независимо от того это имеет смысл или нет. В C ++ нет универсальной базы, и не существует неявного определения ==. == обычно только переопределяется, когда это имеет смысл, для сравнения объектов того же типа, и компилятор будет жаловаться, если вы пишете ерунду код. В тех случаях, когда существует иерархия наследования, это конечно, до автора решить, имеет ли смысл == (Я обычно не, но есть много исключений), и если Итак, что это должно означать при сравнении объектов Различные типы. Внутри иерархии или вне ее: это может иметь смысл поддерживать == между BigInteger и BigFloat, например, даже если классы не связаны наследование.

Причина, по которой вы не видите проблему, много обсуждаемую в C ++, заключается в том, что конечно, потому что вы не определяете ==, если нет логическое значение для этого, а затем вы определяете его в соответствии с логическое значение В Java вы обычно должны определять equals независимо от того, так что вы должны «придумать» какой-то смысл, и вы получите обсуждение того, каким должен быть придуманный смысл.

2 голосов
/ 20 июля 2011

Очевидное отличие состоит в том, что Java equals является виртуальным методом (поскольку все методы Java по умолчанию), поэтому будет выполнять динамическую диспетчеризацию на основе своей цели.

C ++ operator== Перегрузки разрешаются статически, но их легко делегировать виртуальной функции, если вам нужно полиморфное поведение.

За исключением различий в полиморфизме, все остальное поведение полностью зависит от разработчика определенного типа (или, в случае C ++, от реализации автономного operator==).

1 голос
/ 20 июля 2011

Java имеет один базовый тип для всех ссылочных типов - все ссылочные типы расширяются java.lang.Object (по модулю null, который нарушает симметрию equals, поскольку (null).equals(...) является ошибкой).

Таким образом, вы можете сказать в Java "эти две ссылки на Java указывают на эквивалентные вещи?" ничего не зная о типах ссылок, поэтому у Java есть место, где можно повесить метод equals(Object) его базового ссылочного типа, java.lang.Object так, как это не делает C ++. В C ++ такого базового типа нет, поэтому у вас есть множество различных операторов ==, и компилятор должен уметь статически определять, какой из них использовать.

Поскольку объекты Java всегда переносят RTTI, а вся диспетчеризация для метода экземпляра определяется как виртуальная, при определении классов эквивалентности в коде есть вещи, которые вы можете сделать с отражением, которые вы просто не можете сделать с объектами C ++.

0 голосов
/ 20 июля 2011

Чтобы сделать C ++ == эквивалентным для равных Java, предполагается, что вы переопределили оператор == для выполнения "глубоких равных" в C ++, а Java "equals" для того же.

...