2011-07-20 14 views
10

W a question regarding the use of typeid jest C++, zasugerowałem, że można go użyć do porównywania typów w porównaniach obiektów. Nie widziałem zbyt wiele, ale miałem na myśli Java equals.Jaka jest różnica między operatorem Java equals() i C++ ==?

Looking into Java a bit more, to wydaje się być w przypadku: Some say rzeczywiste klasy dwóch obiektów powinny być porównywane, a some sayinstanceof jest właściwym narzędziem do wykorzystania, z możliwością podwójnego wysyłki. Istnieją oczywiście przypadki, w których jeden z nich jest zdecydowanie bardziej odpowiedni, ale przynajmniej both options are considered.

W C++, OTOH, ledwo mogłem znaleźć kod, w którym porównywane są rzeczywiste typy. W większości przypadków używana jest podwójna wysyłka (z dynamic_cast) i nie mogłem znaleźć nikogo, kto nalegałby na szybkie porównanie typów, co należy zrobić na początku sprawdzania równości.

Zastanawiam się, dlaczego problem polimorficznego porównywania typów ma dwa dopuszczalne rozwiązania w Javie, podczas gdy w C++ tylko jeden wydaje się być uważany za najlepszą praktykę? Czy istnieją znaczne różnice techniczne, czy tylko różne podejścia?

Uwaga: Moje roszczenia opierają się na wrażeniu, a nie konkretnej wiedzy. Jeśli są one błędne, a Java i C++ są rzeczywiście podobne pod tym względem - lub inne z powodów innych niż powyższe, to oczywiście będzie to akceptowalna odpowiedź.

+0

W języku C++ '==' może być przeciążone - więc zależy to od kontekstu ... – Schnommus

+2

@Schnommus: W Javie 'equals' może zostać nadpisany. Nie ma dużej różnicy. –

+1

@Ben Voigt: Dobra uwaga. Skasowałbym swój komentarz, gdyby nie dla czytelnika – Schnommus

Odpowiedz

7

W Javie wszystkie rodzaje ostatecznie wywodzą się z Object i Object definiuje wirtualny funkcji Object.equals(Object other), więc można porównać cokolwiek z czymkolwiek innym, niezależnie od tego, czy ma sens czy nie.W C++ nie ma uniwersalnej bazy, a nie ma domyślnej definicji ==. == jest zwykle tylko zastępowany, gdy ma sens, dla porównywania obiektów tego samego typu, a kompilator będzie narzekał, jeśli napiszesz bzdury o kodzie . W przypadkach, w których istnieje hierarchia dziedziczenia, to do autora należy decyzja, czy == ma sens. należy rozumieć w odniesieniu do porównywania obiektów o różnych typach. Wewnątrz hierarchii lub poza nią: może to być na == między BigInteger i BigFloat, na przykład, nawet jeśli klasy nie są powiązane przez dziedziczenie .

Powodem nie widzisz problem omówiono wiele w C++ jest oczywiście, ponieważ nie definiują == chyba że istnieje jakiś logiczny sens dla niego, a następnie zdefiniować je według sensie logicznym . W Javie zazwyczaj musisz zdefiniować equals niezależnie od tego, więc musisz "wymyślić" pewne znaczenie, a otrzymasz dyskusję nad tym, co powinno być wymyślonym znaczeniem.

0

Uczynienie C++ == równoważnikiem równań Java zakłada, że ​​przesłoniłeś operatora ==, aby zrobić "głębokie równe" w C++, a Java "równa się", aby zrobić to samo.

+0

Tak jak powiedziałem, musisz zastąpić równe, aby zrobić głębokie równe. Zobacz Joshua Bloch "Efektywna Java" rozdział 3. – duffymo

+0

wystarczająco fair. Usuwanie mojego oryginalnego komentarza. –

2

Oczywistą różnicą jest to, że Java equals jest metodą wirtualną (ponieważ wszystkie metody Java są domyślnie), więc przeprowadzi dynamiczną wysyłkę w oparciu o jej cel.

C++ operator== przeciążenia są statycznie rozdzielone, ale łatwo jest delegować do funkcji wirtualnej, jeśli chcesz zachować zachowanie polimorficzne.

Z wyjątkiem różnicy w polimorfizmie, każde inne zachowanie zależy wyłącznie od implementatora określonego typu (lub w przypadku C++, implementatora wolnostojącego modelu operator==).

1

Java ma jeden podstawowy typu dla każdego typu odniesienia - Wszystkie odniesienia rozciągają java.lang.Object (modulo null który rozkłada equals symetrię od (null).equals(...) jest błąd).

Można powiedzieć, że w Javie "czy te dwa odwołania do Java wskazują na podobne rzeczy?" nie wiedząc nic o typach referencji, więc Java ma miejsce, aby zawiesić metodę equals(Object) swojego bazowego typu odniesienia, java.lang.Object w sposób, który nie ma C++. W C++ nie ma takiego typu podstawowego, więc masz wiele różnych operatorów ==, a kompilator musi mieć możliwość statycznego obliczenia, którego użyć.

Ponieważ obiekty Java zawsze przenoszą RTTI, a cała wysyłka do metody instancji jest określana jako wirtualna, istnieją rzeczy, które można zrobić z refleksją przy definiowaniu klas równoważności w kodzie, którego po prostu nie można z obiektami C++.

+1

Java '==' wydaje się być nie na temat dla tego pytania. –

+0

@Ben, całkiem dobrze. Dokona edycji. –

Powiązane problemy