Operator &&,Operator ||,Operator ,の3つ
Operator &&,Operator ||,Operator ,の3つはユーザー型で定義しちゃいけない
理由は簡単で
if((pPointer)&&(pPointer->Func())){
//nop;
}
という記述はC++ではよくやる。
で、(pPointer->Func())のほうは(pPointer)がtrueだったときのみ評価される
つまーり、(pPointer)がfalseの場合は(pPointer->Func())は評価されず、Func()の呼び出しは行われない。
これを短絡評価という。
ところで。
operator &&をユーザー定義した場合を考えてみる。
おそらくこの呼び出しは以下のようになる。
//メンバの場合
(expression1).operator&&(expression2);//global定義の場合
operator&&(expression1,expression2);
さてさて・・・
見た瞬間に分かると思うが、関数の実引数の評価順序は決まっていない。
しかも呼び出すにはすべての引数が評価される必要がある。
これはpPointerがNullであってもpPointer->Func()を評価、すなわちFunc()呼び出しを意味する!
演算子がデフォルト定義の演算子と同じように定義されるべきであるとすれば
operator&&,||はその時点でオーバーロードすべきでじゃないってこった。
引き続き,(コンマ)のオーバーロード
コンマ演算子ってなんぞや?ってのは以下をみてみて。
int j=0;
for(int i=0;i<100;++i,++j){
//nop
};
まぁ、よく見るアレですね。
最近では i とかよりも iter だったりするのかも。
んでまー本題。
ちょっと見にくいですが、
++i , ++j
の部分がコンマ演算子となっておりまする。
コンマ演算子は左から順に評価し、一番最後の式を戻り値にします。この場合は式の評価値のことですね。
具体的には
++i が評価され、++j が評価され、この式の値は ++j となっています。
じゃあ operator , の呼び出しをみてみると・・
//メンバの場合
(expression1).operator,(expression2);//global定義の場合
operator,(expression1,expression2);
はい、もうピンときましたね。(きてねーよ
&&や||演算と同じですが、引数の評価順がまったく保障されません。
うまく使うと便利なんですけどねぇ。。。