オブジェクト指向プログラミングの領域では、関連するクラスのオブジェクトが等しいかどうかを比較することが望まれることがよくあります。ただし、クラス階層を扱う場合、等価演算子をオーバーロードするための正しいアプローチを決定するのは難しい場合があります。
次のクラス階層を考えてみましょう。
class A { int foo; virtual ~A() = 0; }; A::~A() {} class B : public A { int bar; }; class C : public A { int baz; };
クラス階層をオーバーロードするには、いくつかのアプローチがあります。このような階層の等価演算子。
演算子==を自由関数としてオーバーロードすると、キャストせずにオブジェクトを直接比較できます。ただし、このアプローチでは、派生クラス (B および C) に対して基本クラス (A) の等価性チェックを利用できなくなります。
仮想メンバー関数のアプローチを使用すると、派生クラスは次のことができます。等価性チェックをオーバーライドします。ただし、これには、冗長に感じる可能性がある異なるタイプのオブジェクトの比較を避けるために動的キャストが必要です。
推奨されるアプローチは、Scott Meyer の「Effective C」で概説されている原則に従うことです。
具体的な基本クラスの宣言を避け、完全な実装がない場合は抽象化します。
非リーフ クラスでは、保護されたクラスを提供します。等価性チェック用の非仮想ヘルパー関数 (isEqual() など)。
リーフ クラスで、ヘルパーを利用するパブリック非仮想等価演算子オーバーロードを定義します。
bool operator==(const B& lhs, const B& rhs) { return lhs.isEqual(rhs) && lhs.bar == rhs.bar; }
このアプローチにより、偶発的なフォールバックが防止され、異なる型のオブジェクトを比較する際の型安全性が保証されます。
階層間の等価性チェックの場合は、純粋仮想関数の使用を検討してください。派生クラスでオーバーライドされる基本クラス内。
bool B::pubIsEqual(const A& rhs) const { const B* b = dynamic_cast<const B*>(&rhs); return b != NULL && *this == *b; }
これらの原則に従うことで、複雑なクラス階層に対して堅牢でタイプセーフな等価演算子のオーバーロードを実現できます。
以上がクラス階層で等価演算子を安全にオーバーロードする方法は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。