0

クラスCOMPLEXをC++で実装し、算術演算子と入出力用の「<<」および「>>」演算子をオーバーロードしようとしています。個別に、またカスケードされた場合、算術演算子は期待どおりに機能しますが、次のようなステートメントを実行しようとすると、正しい結果を取得できません。

cout &lt&lt "something" &lt&lt complex1 + complex2 &lt&lt "\n";

ここで、complex1とcomplex2は、COMPLEXクラスのオブジェクトです。

クラス定義のスニペット:

class COMPLEX{
    int a;  // Real part
    int b;  // Imaginary part
public:
    COMPLEX operator = (COMPLEX );
    COMPLEX operator + (COMPLEX ) const;
    friend istream& operator &gt&gt (istream &, COMPLEX &);
    friend ostream& operator &lt&lt (ostream &, COMPLEX &);
-snip-
}


COMPLEX COMPLEX::operator = (COMPLEX t_c) {
    return COMPLEX(a = t_c.a, b = t_c.b);
}

COMPLEX COMPLEX::operator + (COMPLEX t_c) const{
    return COMPLEX(a + t_c.a, b + t_c.b);
}

istream& operator &gt&gt (istream &i_s, COMPLEX &t_c){
    i_s &gt&gt t_c.a &gt&gt t_c.b;
    return i_s;
}

ostream& operator &lt&lt (ostream &o_s, COMPLEX &t_c){
    o_s &lt&lt t_c.a &lt&lt "+" &lt&lt t_c.b &lt&lt "i";
    return o_s;
}

これとは別に、演算子もオーバーロードしています。

他のオーバーロードされた演算子で<<をカスケードしようとすると、オーバーロードされた<<friend関数が呼び出されません。代わりに、オペレーターが呼び出され、その結果が表示されます。

4

4 に答える 4

1

演算子<<は定数参照を取得する必要があります。そうしないと、コンパイラはCOMPLEX型の一時(加算の結果)を非定数参照にキャストできず、代替演算子<<を検索する可能性があります。電話。

friend ostream& operator << (ostream &, const COMPLEX &); //notice "const"

残りの演算子の仕組みを理解するには、演算子の優先順位テーブルを確認するだけです。

于 2011-02-05T20:51:09.170 に答える
1

問題は、ストリーム挿入演算子が次のように定義されていることです。

friend ostream& operator << (ostream &, COMPLEX &);

COMPLEXこれは、2番目のパラメーターとしてオブジェクトへの非定数参照を取ります。書いてみると

cout << a + b << endl;

の値はa + b、関数によって返される値であるため、左辺値ではなく右辺値です。C ++では、参照を右辺値にバインドすることはできません。それ以降、次のような悪いことを行う可能性があります。operator +

COMPLEX& c = a + b; // This step isn't legal
c = 137;            // Wait, what object did we just change?

ここでの問題は、cによって返される一時オブジェクトへの参照をバインドできる場合a + b、その参照を使用してそのオブジェクトに変更を加えることができるということです。しかし、これは意味がありません。これはa + b式の値であり、実際のオブジェクトではありません。

これは、ここで起こっているのと同じ問題です。は右辺値であるため、関数は2番目のパラメーターとして使用できませoperator <<ん。a + ba + b

これを修正するには、COMPLEXoperator <<const参照するように変更できます。

friend ostream& operator<< (ostream& out, const COMPLEX& c);

これが機能するのは、C++ではconst参照を右辺値にバインドできるためです。この背後にある理論的根拠は、一時オブジェクトへのconst参照がある場合、その一時オブジェクトに変更を加えることができないため、参照をバインドする上記の例a + bはもはや問題ではないということです。

一般に、型がそのインスタンスを変更しないクラスの別のインスタンスであるパラメーターを受け取るオーバーロードされた演算子は、const参照によってそのパラメーターを受け取る必要があります。これは、この問題を回避するため、、などoperator =の場合に当てはまります。operator +

于 2011-02-05T20:54:16.220 に答える
0

coutステートメントを次のように書き直します

cout << "something" << (complex1 + complex2) << "\n";
于 2011-02-05T20:25:52.527 に答える
0

問題は、operator<<が常にoperator+の前に呼び出されることです。オーバーロードを提供しても、これは変わりません。

一方、計算の順序を確認するのが難しくなるため、通常、計算をI / Oと混合しないでください(おそらく入力を節約するためだけに)。

于 2011-02-06T11:16:17.113 に答える