10

の使用に関する質問で、typeid C ++を使用して、オブジェクト比較で型を比較できることを提案しました。私はそれがあまり行われていないのを見たことがありませんが、Javaequalsを念頭に置いていました。

Javaをもう少し詳しく見てみると、これが当てはまるようです。2つのオブジェクトの実際のクラスを比較する必要があると言う人もいれば、おそらくダブルディスパッチで使用するのに適切なツールであると言う人もいます。 instanceofもちろん、2つのうちの1つが決定的に適している場合もありますが、少なくとも両方のオプションが考慮されます。

C ++、OTOHでは、実際の型が比較されるコードをほとんど見つけることができませんでした。ほとんどの場合、ダブルディスパッチが使用され(とdynamic_cast)、等価性チェックの開始時に迅速な型比較が正しいことであると主張する人は誰も見つかりませんでした。

ポリモーフィック型の比較の問題がJavaで2つの受け入れ可能な解決策を持っているのに、C ++では1つだけがベストプラクティスと見なされているように見えるのはなぜだろうか?技術的に大きな違いはありますか、それとも単に異なるアプローチですか?

注:私の主張は、具体的な知識ではなく、印象に基づいています。それらが間違っていて、JavaとC ++がその点で実際に類似している場合、または上記以外の理由で異なる場合、それは明らかに許容できる答えになります。

4

4 に答える 4

7

Javaでは、すべての型が最終的にはから派生し 、仮想関数Objectを定義するため、意味があるかどうかに関係なく、他のものと何でも比較できます。C ++には、一義的なベースはなく、。の暗黙的な定義もありません。 通常、同じタイプのオブジェクトを比較するために意味がある場合にのみオーバーライドされ、意味のないコードを記述した場合、コンパイラは文句を言います。継承階層がある場合は、もちろん、意味があるかどうかを判断するのは作成者次第です(通常は意味がありませんが、多くの例外があります)。そうであれば、それが何を意味するのかを判断します。異なるタイプのオブジェクトを比較します。階層内または階層外:との間で サポートすることは理にかなっているかもしれませんObjectObject.equals(Object other)========BigIntegerBigFloatたとえば、クラスが継承によって関連付けられていない場合でも。

もちろん、C ++で問題があまり議論されていない理由は、==論理的な意味がない限り定義せず、論理的な意味に従って定義するためです。Javaでは、通常、equals 関係なく定義する必要があるため、何らかの意味を「発明」する必要があり、発明された意味がどうあるべきかについて話し合います。

于 2011-07-20T20:28:03.173 に答える
2

明らかな違いは、Javaequalsは仮想メソッドであるため(すべてのJavaメソッドがデフォルトであるため)、そのターゲットに基づいて動的ディスパッチを実行することです。

C ++operator==のオーバーロードは静的に解決されますが、ポリモーフィックな動作が必要な場合は、仮想関数に簡単に委任できます。

ポリモーフィズムの違いを除いて、他のすべての動作は完全に特定のタイプの実装者(またはC ++の場合は自立型の実装者operator==)次第です。

于 2011-07-20T19:37:42.013 に答える
1

Javaには、すべての参照型に対して単一の基本型があります。すべての参照型が拡張されますjava.lang.Object(モジュロはエラーであるため対称性nullを破ります)。equals(null).equals(...)

つまり、Javaでは、「これら2つのJava参照は同等のものを指しているのでしょうか?」と言うことができます。参照の型について何も知らないので、Javaには、C ++がそうではないequals(Object)方法で、その基本参照型のメソッドをハングアップする場所があります。java.lang.ObjectC ++にはそのような基本型がないため、多数の異なる==演算子があり、コンパイラーはどちらを使用するかを静的に把握できる必要があります。

Javaオブジェクトは常にRTTIを実行し、インスタンスメソッドへのすべてのディスパッチは仮想として指定されるため、コードで等価クラスを定義するときに、C++オブジェクトでは不可能なことをリフレクションで実行できます。

于 2011-07-20T19:39:33.213 に答える
0

C ++ ==をJavaのequalsと同等にすることは、==演算子をオーバーライドしてC ++で「ディープイコール」を実行し、Javaの「equals」をオーバーライドして同じことを実行することを前提としています。

于 2011-07-20T19:36:35.587 に答える