シナリオ
平等に比較できるようにしたいクラスがあります。クラスは大きく (ビットマップ イメージが含まれています)、複数回比較するので、効率を高めるためにデータをハッシュし、ハッシュが一致する場合にのみ完全な等価性チェックを行います。さらに、オブジェクトの小さなサブセットのみを比較するため、等価性チェックが最初に実行されたときにのみハッシュを計算し、その後の呼び出しには保存された値を使用します。
例
class Foo
{
public:
Foo(int data) : fooData(data), notHashed(true) {}
private:
void calculateHash()
{
hash = 0; // Replace with hashing algorithm
notHashed = false;
}
int getHash()
{
if (notHashed) calculateHash();
return hash;
}
inline friend bool operator==(Foo& lhs, Foo& rhs)
{
if (lhs.getHash() == rhs.getHash())
{
return (lhs.fooData == rhs.fooData);
}
else return false;
}
int fooData;
int hash;
bool notHashed;
};
バックグラウンド
この回答のガイダンスによると、等値演算子の正規形は次のとおりです。
inline bool operator==(const X& lhs, const X& rhs);
さらに、演算子のオーバーロードに関する次の一般的なアドバイスが提供されます。
常に、オペレーターの既知のセマンティクスに固執してください。
質問
私の関数は、ハッシュを実行するためにそのオペランドを変更できる必要があるため、それらを non- にする必要がありました
const
。これによる潜在的な悪影響はありますか (例としては、標準ライブラリ関数や、オペランドoperator==
を持つことを期待するSTL コンテナーなどがあります)。const
operator==
ミューテーションが観察可能な効果を持たない場合 (ユーザーがハッシュの内容を見る方法がないため)、ミューテーション関数はよく知られているセマンティクスに反していると見なされるべきですか?上記のいずれかに対する答えが「はい」の場合、より適切なアプローチは何ですか?