2011-01-12 33 views
3

私は現在、古いC++のコードベースを検討し、次のように起こって多くのコードを参照してください。"operator =="は常にC++の "operator =="で実装する必要がありますか?

はっきり
bool SomeClass::operator==(const SomeClass& other) const 
{ 
    return member1 == other.member1 && member2 == other.member2; 
} 

bool SomeClass::operator!=(const SomeClass& other) const 
{ 
    return member1 != other.member1 || member2 != other.member2; 
} 

比較ロジックが複製され、上記のコードは、おそらく2つの場所ではなく、1に変更する必要があります。論理変化はそれだけoperator==を呼び出して否定を実行するので、自動的にoperator!=に反映されますoperator==で起こるどんな後者の場合

bool SomeClass::operator!=(const SomeClass& other) const 
{ 
    return !(*this == other); 
} 

operator!=を実装する典型的な方法私の知る限り

は次のようです。

operator!=は、operator==をC++コードで再利用する以外は、他の方法で実装する必要がありますか?

+2

同様に、少なくとも冗長な方法で '>、> =、<=、<'演算子を実装しようとする必要があります。 –

+0

ルールは絶対であってはなりません。すべてのルールは一般的に成立します。しかし、私は彼らがいない特定のインスタンスが常に存在すると確信しています。しかし、(あなたがそれを昨日やったことがない限り)1人で登場することは一般的には不可能です(ルールの例外であるため)。そのような質問は、すべて白鳥です。はい、すべての白鳥は白です(オーストラリアで白鳥が発見された1500年まで)。覚えておいてください: "terara nigroque simillima cygnoのrara avis" –

答えて

9

ほとんどの場合、a!=bのセマンティクスは!(a==b)に等しくなければなりません。

同じ約他のすべてのオペレータのために真である:a<bはそうで等!(a=>b)および!(a==b || a>b)およびa<=b && !(a==b)に等しくなるとすべきです。

boost.operatorsには、他の機能に合わせて自動的に演算子を生成するいくつかのすばらしいツールがあります。


しかし、あなたのオペレータにいくつかの特定のセマンティクスを与えるとき(すなわち:あなたは2つの項目が同じであるかどうかを確認するために==を使用しませんが、STLは>><<でないようないくつかの派手なものを行うために)あなたそれらに異なる実装を与えることができます。

この練習は、一般的には示唆されていませんが、STLや多くのブーストライブラリでさえそうです。


EDIT - 少し加え:

私が言った演算子のこれまで懸念だけの意味。
bool operator!=(a,b) { return !(a==b); }

:あなたはboost.operatorsを使用した場合に何が起こるかである他のオペレータを呼び出すことによって

  • :あなたのa!=bの意味は!(a==b)あなたがそれを実装する2つの方法を持っているべきであると判断した場合

  • 両方をゼロから実装する。

通常、最初の方法は実装が簡単で安全です。2番目のオプションを正当化する最も一般的なことは、おそらくそれほど価値がないかもしれませんが、最適化です。現代のコンパイラはほとんどの場合オーバーヘッドを追加しません(boost.operatorsソースコードを見れば、コンパイラがNRVOを提供しない場合、オーバーヘッドを追加しないように、またはコードがどのように変更されるかに頼ってNRVOに依存してください)。

どのようなオプションを選択しても、アプリケーションのロジックに違いはありません。意味はセマンティクスです(つまり、オペレータの行動、可能な入力に対して返すもの)。

+2

+1 Boost.Operators、それはどのように小さなライブラリは非常に簡単に演算子を実装することが驚くべきことです。依存関係を取り除くだけでなく、目立った間違いを取り除くこともできます(例えば、<<'のような' <= 'で実装する場合は引数を切り替えます)。 –

4

IMHO == =の点で実装するのは妥当で堅牢です。

+0

-1間違った提案。どのように '=='を '!='の形で実装できますか? – Nawaz

+4

@Nawaz: 'a == b iff!(a!= b)'。それは定義によるものです。 –

+4

あなたは正しいので何も修正する必要はありません。 –

2

意味論的に意味があります(==は=の論理的補数でなければならないことを意味しますが、実質的に(コーディング)する必要はありません)。

+4

私は意味論的にあなたは*必要ではないと言っていますが、実際はあなたは*すべきです*。 –

+0

私は==は意味の補完的なものでなければならないことを意味します!=、しかし実際に(プログラミングでは)それを否定を暗示するために使用する必要はありません。 –

+0

あなたは間違っていたり何かではなかった。物を見るのはちょっと違う。あなたが「事実上」C++のルールに関わっていると言ったとき、私が「実質的に」言ったとき、私は維持しやすいモジュールコードに関心を持っていました。あまりにも多くの私のコメントに読んではいけません:) –

3

operator!=は、operator==をC++コードで再利用する以外は、他の方法で実装する必要がありますか?

私はそうは思わない。しかし、他のコードについても同様である。 postfixの++常には(オプティマイザはより効率的なコードを生成することができますネイティブ型のためのコースの除いて、私は、引数が保持しても信じて)接頭++の観点で実施されるべきであるとoperator +はほとんど常にはの面で実装する必要がありますoperator +=(実行を遅らせるためにプロキシオブジェクトを使用している場合は例外です)。

これは、std::relopsが存在する理由です。

関連する問題