1. ホーム
  2. c++

[解決済み] 演算子のオーバーロード:メンバ関数と非メンバ関数?

2022-06-25 05:08:36

質問

メンバ関数として宣言されたオーバーロードされた演算子は 非対称 というのは、パラメータをひとつしか持てず、自動的に渡されるもうひとつのパラメータは this ポインタです。そのため、両者を比較する基準は存在しない。一方、オーバーロード演算子として宣言されたものは friend 対称 というのは、同じ型の二つの引数を渡しているので、比較することができるからです。

私の質問は、ポインタの lvalue を参照と比較できるのに、なぜ友人が優先されるのか、ということです。(非対称バージョンを使用すると、対称と同じ結果が得られます)。 なぜ STL アルゴリズムは対称バージョンのみを使用するのでしょうか?

どのように解決するのですか?

演算子オーバーロード関数をメンバ関数として定義した場合、コンパイラは以下のような式を変換します。 s1 + s2s1.operator+(s2) . つまり、演算子オーバーロードされたメンバ関数が最初のオペランドで呼び出されることになります。 それがメンバ関数の動作方法です!

しかし、もし最初のオペランドがクラスでない場合はどうでしょうか? 最初のオペランドがクラス型でない演算子をオーバーロードしたい場合、大きな問題があります、むしろ、例えば double . ですから、次のように書くことはできません。 10.0 + s2 . しかし、以下のような式に対して、演算子オーバーロードされたメンバ関数を書くことができます。 s1 + 10.0 .

これを解決するために の順序 の問題を解決するために、演算子のオーバーロード関数を次のように定義します。 friend にアクセスする必要がある場合 private のメンバーにアクセスする必要があります。 にする。 friend プライベートなメンバにアクセスする必要があるときだけ。 それ以外の場合は、単純に 非友人非会員 という機能を 向上させる を向上させます。

class Sample
{
 public:
    Sample operator + (const Sample& op2); //works with s1 + s2
    Sample operator + (double op2); //works with s1 + 10.0

   //Make it `friend` only when it needs to access private members. 
   //Otherwise simply make it **non-friend non-member** function.
    friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}

これらを読んでください。

オペランドの順序に関する若干の問題

非メンバー関数がカプセル化を改善する方法