2012-01-03 18 views
1
#include <iostream> 
#include <fstream> 
using namespace std; 

class binaryOperators 
{ 
    public: 
     int i; 

     binaryOperators (int tempI = 0) 
     { 
      i = tempI; 
     } 

     binaryOperators operator<< (const binaryOperators &right); 
}; 

binaryOperators operator<< (const binaryOperators &left, const binaryOperators &right) 
{ 
    cout << "\nOne"; 
    return left; 
} 

binaryOperators binaryOperators :: operator<< (const binaryOperators &right) 
{ 
    cout << "\nTwo"; 
    return *this; 
} 

int main() 
{ 
    binaryOperators obj; 

    // Compiler's behavior: This statement calls the overloaded operator << declared inside the class. 
    obj << 5 << 3 << 2; 
    // Compiler's behavior: This statement calls the overloaded operator << declared outside the class. 
    2 << obj; 

    return 0; 
} 

main()関数内のコメントを書きました。
この種のコンパイラの動作の理由は何ですか?オーバーロードされた演算子のオーバーロード

この動作はコンパイラに依存しますか?

LinuxのGCC

+1

実際には、より良い変数名を書くようにしてください。 'l'は' 1'と非常によく似ています。 – Default

+0

@Default申し訳ありませんが、次回は気をつけます。 –

+0

新しい投稿を新規投稿してください。そうしないと、通知が届きません。 –

答えて

2

あなたが見ている動作は、const正しさに起因しています。クラス内で定義された演算子< <は非constなので、objなどの非constオブジェクトまたは参照に対してのみ操作できます。クラス外の非メンバーバージョンには、2つの定数オペランドがあります。

あなたは非会員として加盟バージョンを書いた場合、それは次のようになります。過負荷マッチング、コンパイラはベストフィットを選択すると

binaryOperators operator<< (binaryOperators &left, const binaryOperators &right) 
{ 
    cout << "\nTwo"; 
    return left; 
} 

。最初のケースでは、左のオペランドは非constなので、メンバー演算子を選択します。 2番目のケースでは、左側のオペランドはrvalue(一時的なbinaryOperators)です。これはconstとして参照されるため、非メンバー演算子が選択されます。

+0

参照を返すことを意味しましたか? –

+0

私はこれを、OPによって提供されるオペレータ実装に基づいています。確かにリファレンスを返すのは、ユーザーの期待に沿ったものになるだろうが、やはり機能性が失われてしまう。 – zennehoy

+0

ここで値を返すと、次の '<<'はLHSとして 'コンス'の参照を期待しているので、メンバー演算子を使うことはできません。それが私の主張です。 :) –

2

この動作は完全に理にかなって:

  • メンバ関数が存在し、一致した場合、フリー機能に優先して、それを使用するのは良い考えである、そうでない場合は、クラス外のコードが誤って壊す可能性がありクラスのカプセル化(たとえば、別のメンバー関数がoperator<<を使用する場合)。

  • 自動変換では、候補関数のリストを作成し、それを必要とするパラメータの変換を見つけようとします。メンバ関数を見つけるために、候補リストを構築する前に変換が行われなければならないので、空き関数だけが見つかる。

+0

を編集しました。そのため、Scott Meyerはメンバー関数として演算子を作成しないようにアドバイスしています。あなたのタイプの暗黙の変換の恩恵を受けるためには、常に自由な関数としてそれらを作成する必要があります。 –

+0

@TobiasLangnerは 'friend'を使って? @サイモン、答えに感謝します。 –

+1

プライベート/保護されたメンバーに直接アクセスする必要がある場合にのみ、友人を使用してください。カプセル化を最大にするには、演算子は非メンバーでない非友人でなければなりません。http://www.gotw.ca/gotw/084.htmも参照してください。 – zennehoy

関連する問題