メンバー関数として宣言されたオーバーロードされた演算子は、1つのパラメーターしか持たず、自動的に渡されるもう1つのパラメーターが 'this'ポインターであるため非対称です。したがって、それらを比較する標準は存在しません。一方、同じ型の2つの引数を渡すため、友人として宣言されたオーバーロードされた演算子は対称です。したがって、それらを比較することができます。 私の質問は、私はまだポインタのlvalueを参照と比較することができますが、なぜ友人が優先されるのですか? (非対称バージョンを使用すると対称と同じ結果が得られます) STLアルゴリズムは対称バージョンのみを使用するのはなぜですか?演算子のオーバーロード:メンバ関数と非メンバ関数の比較?
答えて
演算子オーバーロードされた関数をメンバー関数として定義すると、コンパイラはs1 + s2
のような式をs1.operator+(s2)
に変換します。 つまり、演算子のオーバーロードされたメンバー関数は、最初のオペランドで呼び出されます。これはメンバー関数の仕組みです!
しかし、最初のオペランドがクラスでない場合はどうなりますか? 最初のオペランドがクラス型ではなく、むしろdouble
という演算子をオーバーロードしたい場合、大きな問題があります。だからこのように書くことはできません10.0 + s2
。しかし、s1 + 10.0
のような式の演算子のオーバーロードされたメンバー関数を書くことができます。それはprivate
メンバーにアクセスする必要がある場合
friend
ように、オペレータオーバーロードされた関数を定義します。
プライベートメンバーにアクセスする必要がある場合のみ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
}
これらを読む:
A slight problem of ordering in operands
How Non-Member Functions Improve Encapsulation
"プライベートメンバーにアクセスする必要がある場合にのみ、それを' friend'にしてください。アクセサーを書くのに飽きたときはどうですか? – badmaash
@Abhi:あなたの選択を選んでください:改良されたカプセル化とレイジーな習慣! – Nawaz
グローバルな 'operator +()'を単に 'return op2.operator +(op1);'にすることによって、 'friend'キーワードを避けることができなかったケース?どちらの場合でも、+はデフォルトで入力Sampleを変更しません。代わりに 'Sample'の新しい右辺値のインスタンスを返します。右は – matthias
がグローバルオペレータのオーバーロードとメンバ関数演算子オーバーロードの間にあるように、それは必ずしもfriend
オペレータのオーバーロードとメンバ関数演算子のオーバーロードとの間の区別はありません。あなたはクラス型は、二項演算子の右手元側に現れる場所を表現できるようにしたい場合はグローバル演算子オーバーロードを好む
一つの理由です。例えば:
Foo f = 100;
int x = 10;
cout << x + f;
Fooの演算子+(INT X、CONST Fooの& F)のグローバルオペレータ過負荷がある場合にのみ動作します。
グローバル演算子のオーバーロードは、必ずしもfriend
関数である必要はありません。これは、Foo
のプライベートメンバーにアクセスする必要がある場合にのみ必要ですが、必ずしもそうであるとは限りません。かかわらず
、Foo
だけのように、メンバー関数の演算子オーバーロードを持っていた場合:その後、我々は唯一のFoo
インスタンスはプラスのを残しに表示される場所の表現を持っていることができるだろう...
class Foo
{
...
Foo operator + (int x);
...
};
オペレーター。
で説明されている多くのトピックの1つです。メンバー関数とフレンド関数ではなくメンバ関数と非メンバ関数を区別するために、図1に示す。私たちは今日、「グローバルまたはネームスペースの範囲」と言います。 –
- 1. 非仮想オーバーロードされたメンバ関数
- 2. angularjsの比較演算子関数
- 3. 比較演算子への関数ポインタ
- 4. 演算子とフレンド関数のオーバーロード
- 5. STL - 代入演算子対代入メンバ関数
- 6. C++演算子非静的メンバ関数でなければなりません
- 7. メンバ関数&constメンバ関数ポインタ控除
- 8. 構造体演算子関数のオーバーロード
- 9. constexprの非メンバ関数と参照アルゴス
- 10. C++の演算子のオーバーロード(比較演算子)
- 11. メンバー関数vs演算子オーバーロード
- 12. C++ std :: set Find関数オーバーロード==演算子
- 13. メンバ関数をメンバ関数のパラメータとして渡す
- 14. 非メンバ関数ポインタが必要なときにメンバ関数ポインタを渡す?
- 15. メンバ関数とコピーコンストラクタ
- 16. オーバーロード比較です演算子「無効な演算子は、<」
- 17. クラスのメンバ関数
- 18. CakePHPの「非オブジェクトのメンバ関数」を
- 19. C++メンバ関数へのポインタ、メンバ
- 20. 非メンバ関数ロックの使い方
- 21. 非静的C++メンバ関数へのコールバック
- 22. 関数クラスの乗算(加算、...)演算子のオーバーロード
- 23. Xval演算子と比較演算子?
- 24. 乗算演算子をメンバー関数としてオーバーロードする
- 25. C++のメンバ関数への関数ポインタ
- 26. 複数の比較演算子
- 27. 同じ演算子とクラスの2つのオーバーロード関数
- 28. C++メンバ関数ではない演算子を書く方法は?
- 29. C++メンバ関数ポインタ
- 30. Dメンバ関数は、
あなたの質問は唯一の二項演算子について実際にあります。すべてのオーバーロードされた演算子が単一のパラメータに制限されているわけではありません。 ()演算子は任意の数のパラメータを取ることができます。一方、単項演算子はパラメータを持つことはできません。 –
http://stackoverflow.com/a/4421729/103167 –
[C++ FAQ:オペレータのオーバーロード](http://stackoverflow.com/questions/4421706/operator-overloading) –