2011-02-05 11 views
0

私はC++でクラスCOMPLEXを実装しようとしており、算術演算子に加えて入出力のために '< <'と '>>'演算子もオーバーロードしています。個別とも予想されるように算術演算子の仕事をカスケード接続する場合 - しかし、のようなステートメントを実行しようとしたとき、私は正しい結果を得ることができません:complex1とcomplex2がクラスCOMPLEXのオブジェクトであるオーバーロードされた算術演算子を使用して、オーバーロードされた抽出演算子をカスケードすることは可能ですか?

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

を。クラス定義の

スニペット:

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; 
} 

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

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

答えて

1

問題は、あなたのストリーム挿入演算子は

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

これは2番目のパラメータとしてCOMPLEXオブジェクトへの非const参照を取るように定義されていることです。あなたは

cout << a + b << endl; 

を書くしようとすると、それが機能operator +によって返された値だからa + bの値は、右辺値、ない左辺値です。そして、あなたは、このような悪いことを行うことができますので、C++では、あなたは、右辺値への参照をバインドすることはできません。

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

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

これはここで起こっているのと同じ問題です。 a + bは右辺ですので、operator <<関数はa + bを第2パラメータとすることはできません。

これを修正するには、COMPLEXへconst参照を取るためにoperator <<を変更することができます:C++で使用すると、右辺値へのconst参照をバインドすることができますので、

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

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

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

+0

ありがとう:)私が探していた説明だけ – kny8mare

0
に(ほかに起因する)あなたのオペレータ< <は、一定の基準を取る必要がそうでない場合、コンパイラは型COMPLEXの一時的にキャストすることはできません
+0

はい!私は以前にそれを試して、それは動作します。しかし、私はcout << 1 + 2のような操作を実行できるかどうか疑問に思っていました。それではこれも上記のことを守るべきでしょうか? – kny8mare

+0

あなたの方法を試して..まだ動作していない。結果は以前と同じようにintに型キャストされています。私はこの作業を行うことができる唯一の方法は、COMPLEX型の3番目のオブジェクトに結果を代入してからそれを計算することです。 – kny8mare

1

cout << "something" << (complex1 + complex2) << "\n"; 
にご cout文を書き直し

非const参照であり、代替演算子< <を呼び出すことがあります。

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

オペレータ力学の残りの部分を理解するために、あなただけのoperator precedence tableを見てする必要があります。

0

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

一方、計算の順序を見るのが難しいため、一般的には計算とI/Oを混在させないでください(一部の型を保存するためにのみ)。

関連する問題