14

つまり、クラス内で演算子<<をオーバーロードしようとしていました

このような

 class A {
      public:
           ostream &operator<<(ostream &os);// which doesnt work

      private:
           friend ostream &operator<<(ostream &os, const A& a); //Works
           int i;

 };

  Definition
          ostream &operator<<(ostream &os, const A& a) {
              os<<a.i;
              return os;
          }

クラスに固有のクラス内で演算子をオーバーロードできないのはなぜですか?または私は何かが欠けていますか?または私はそのように考えることさえ愚かですか?お知らせ下さい。

4

3 に答える 3

31

問題は、最初のパラメータではなく、2番目のパラメータとして使用するoperator<<ことです。ostreamそうすればできますが、直感的ではないように見え、結合性が残っているmyObject << std::coutために呼び出しを連鎖させることができません。operator<<

メンバー関数ではなく、演算子をフレンドとして宣言することのもう1つの利点は、自動変換が発生する可能性があることです。つまり、B派生していないAがコンストラクターを持っているクラスがある場合でも、それを実行して、に変換してから出力するB(A const&)ことができます。std::cout << my_b;A

幸い、必要に応じて、クラス内で友達として定義するoperator<<ことができます。あなたのコードは次のように書くことができます

class A {
    int i;
    friend std::ostream& operator<<(std::ostream& o, A const& a) {
        o << a.i;
        return o;
    }
};

なぜ標準では、引数をどちら側に進めるかを指定できないのですか?それが行われたふりをして、指定するキーワードleft_ofとキーワードを追加しましょう。right_of

struct B;

struct A {
     A left_of operator+(B const&) {
         return *this;
     }
};

struct B {
     B right_of operator+(A const&) {
         return *this;
     }
};

私たちがやると今何が起こりますA a; B b; f(a + b);か?各クラスには、このケースを処理する演算子があります。つまり、決定できません。とにかく変換​​の可能性があるため、多くのオペレーターが友達になるはずですが、この種のことを許可しないことはそれほど大きな問題ではなく、この種のあいまいさを防ぎます。(もちろん、メンバー演算子と無料の演算子を定義することもできます。これにより、非常によく似た問題が発生します。)

ちなみに、物事がそうであるように、あなたの定義はfriend operator<<何も返さないので、連鎖を台無しにします。

于 2012-02-19T17:03:57.987 に答える
27

メンバー関数:

ostream &operator<<(ostream &os);

動作しますが、希望する状況では動作しません。次のようなことをすると呼び出されます。

A a;
a << std::cout;

つまり、オブジェクトが演算子の左側にある場合です。

于 2012-02-19T17:04:37.823 に答える
2

クラスの非静的メンバー関数の場合、最初の引数はこのポインターであることを忘れないでください。したがって、コンパイル後の「operator <<」関数のシグネチャは、次のようになります。

ostream &operator<<(A *this, ostream &os);

これは、次のようなことを行うと機能します。

A obj;
obj << std::cout;

「obj」を最初の引数、「std::cout」を演算子「<<」の2番目の引数と考えてください。

"<<"をオーバーロードするより良い方法は、フレンド関数を使用することです。これにより、オーバーロードされた演算子を結合させることができます。

于 2018-04-03T12:08:51.373 に答える