C の仮想代入演算子
C の代入演算子は仮想として宣言できますが、なぜこれが必要なのかという根本的な疑問が生じます。また、他の演算子も同様に仮想化できますか?
代入演算子は仮想化する必要がありますか?
一般に信じられていることに反して、代入演算子は本質的に仮想化する必要はありません。
仮想関数とパラメータについて継承
仮想関数はポリモーフィズムを有効にし、派生クラスが基本クラス関数をオーバーライドできるようにします。ただし、仮想関数はパラメータの継承を意識しないことを理解することが重要です。
パラメータ継承の制限を示す例:
クラス B と D を使用した次の例を考えてみましょう。 B には仮想代入演算子があり、D はそれをオーバーライドします。
class B { public: virtual B& operator=(const B& right) { x = right.x; return *this; } int x; }; class D : public B { public: virtual D& operator=(const D& right) { x = right.x; y = right.y; return *this; } int y; };
この例ではこのシナリオでは、B::operator= の仮想指定にもかかわらず、パラメーターと戻り値が異なるため、呼び出しは D の仮想関数として扱われません。
Virtual を使用したデフォルト値によるオーバーロードされた演算子
代入演算子は本質的に仮想ではありませんが、派生関数のデフォルト値を含む仮想関数を定義すると有益な場合があります。
class D : public B { public: virtual D& operator=(const D& right) { x = right.x; y = right.y; return *this; } virtual B& operator=(const B& right) { x = right.x; y = 13; // Default value return *this; } int y; };
このアプローチにより、B 参照に割り当てられるときに D オブジェクトにデフォルト値を割り当てることができます。
包括的な型処理に RTTI を採用
最後に、実行時型情報 (RTTI) を使用して、型に関係する仮想関数を処理できます。
virtual B& operator=(const B& right) { const D *pD = dynamic_cast<const D*>(&right); if (pD) { x = pD->x; y = pD->y; } else { x = right.x; y = 13; // Default value } return *this; }
これらの手法を組み合わせることで、継承を伴う代入操作を包括的に処理し、派生型の適切な動作を保証できます。
以上がC ではなぜ仮想代入演算子が必要ですか?また、他の演算子も仮想化できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。