私が C++ で学んだすべてのこと (それほど多くはありません) の中で、演算子のオーバーロードが最も難しいようです。一般的に、演算子のオーバーロードをフレンド関数として記述するのが最適なのはいつですか? いつ明示的に使用する必要があります*this
か? 一時オブジェクトを使用するのは常に悪いですか?
4 に答える
魔法の abourt 演算子のオーバーロードはありません。そのようなオーバーロードは、奇妙に見える名前の単なる関数です。したがって、名前付き関数を記述するのと同じ方法で、演算子のオーバーロードを記述します。実際、最初に名前付き関数を作成することをお勧めします。後でいつでも演算子に変更できます。
注意しなければならない唯一のことは、コンパイラがいくつかの演算子を使用することです。
- コレクションに物を格納するときの operator=()
- operator<() ソート/検索時の
ニールの答えは正しいです。さらに、このリンクは、C++ でさまざまなタイプの演算子のオーバーロードをいつ、どこで、なぜ、どのように使用するかについて、多くの優れた情報を提供します。
一般に、私は直感的なオーバーロードに固執しようとします。「+」演算子の使用は、加算などに類似したものを反映する必要があります。「+」演算子またはそのようなものを使用して文字列比較を行っていることに気付いた場合は、おそらく代わりに標準関数を使用する必要があります。
演算子のオーバーロードの最初のルール: 意味のない演算子をオーバーロードしないでください。たとえば、 + 演算子はリストに要素を追加するのに適しているように見えるかもしれませんが、そうではありません: 誰もがこの使用法を論理的だと思うわけではありません。
算術演算子に関しては、friend
不要です。
それらを定義する典型的な方法 (対称性と暗黙の変換を尊重する) は次のとおりです。
struct T {
T& operator+=(T const& rhs) {
// the actual addition code
return *this;
}
};
T const operator+(T const& lhs, T const& rhs) {
return T(lhs) += rhs;
};
ただし、この構成は、演算子がそれほど自明ではないためMatrix
、
Polynomial
乗算などの演算子には適していません。*=(T const&)
その場合、operator*=(T const&)
の上に を定義し、内部データへのアクセサがない場合 (この の使用はカプセル化違反ではなく、カプセル化の強制)、または最適化の目的でoperator*(T const&, T const&)
バイナリoperator*()
を作成できます。friend
friend
ほとんどの一時変数を本当に排除したい場合は、式テンプレート (Blitz++、boost.ublas、newmat などを参照) を確認するか、C++0x 右辺値参照を待ちます。
メンバー関数が*thisを左辺値として取るため、すべての演算子はオーバーロードします。したがって、<<や>>などのオーバーロードストリーム演算子が必要ない場合は、フレンドが必要です。他のほとんどの場合、フレンドの使用は、最小特権。言われていなかった演算子をオーバーロードする他の方法は、グローバル関数を使用することです。