web-dev-qa-db-ja.com

比較演算子のオーバーロード

これがベストプラクティスです(この場合)。

bool Foo::operator==(const Foo& other) {
  return bar == other.bar;
}

// Implementation 1
bool Foo::operator!=(const Foo& other) {
  return bar != other.bar
}

// Implementation 2
bool Foo::operator!=(const Foo& other) {
  return !(*this == other);
}

>、<、<=、> =などの演算子の場合、可能な場合は実装2を使用します。ただし、!=の場合、別のメソッド呼び出しが行われないため、実装1の方が良いと思いますが、これは正しいですか?

35
blaze

2番目の実装には、==が常に!=とは反対のブール値になるという顕著な制約があります。これはおそらくあなたが望むものであり、1つの実装を変更するだけで2つの同期を維持できるため、コードの保守が容易になります。

32
zneak

比較演算子をオーバーロードするときは、常に持っているものを使用する必要があります。定義する必要があるのは、operator==operator<の2つだけです。残りは、これら2つの観点から記述できます。ミスを犯しているかのように、エラーが発生しにくいため、1か所にしかありません。

OOPの主な機能の1つは、コードの再利用性です。すでにコードを作成しているのに、なぜそれを再度作成するのですか? 。

それはむしろ、定数を宣言し、それをファイル全体のいくつかの場所で使用するようなものです。

12
chris

実装2は、既に定義されているoperator ==を使用するため、より優れています。また、これらの演算子関数はオブジェクトを変更しないため、constである必要があります。

4
sashang

上記のどれでもない。

本当にこれを詳細に説明している論文を見つけられたらいいのにと思いますが、名前は思い出せません。

比較操作は外部である必要があります。インターフェイスはオブジェクトの状態を見つけるのに十分であり、オブジェクトの状態は比較を指示する必要があります。クラスの外で「等しい」と書くことができるはずです。したがって、実際に比較を行うことができます。

3
Edward Strange

一般的に、多くの理由で実装2の方が優れています。まず、重複するコードを(ほとんど)書かないでください。変更する必要がある場合(クラスが成長したか、バグがあったため)、再度実装2を使用すると、1箇所のみ変更します。つまり、実装2により、コードの一貫性が高まり、エラーが発生しにくくなります。

2
Shahbaz