2011-02-05 40 views
0

我試圖在C++中實現一個類COMPLEX,並且重載了算術運算符以及用於輸入/輸出的'< <'和'>>'運算符。單獨地也當級聯如預期的算術運算符的工作 - 但試圖執行的語句,例如當我無法獲得正確的結果:是否有可能通過重載算術運算符級聯重載提取運算符?

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

其中complex1和complex2是類複雜的對象。類定義的

片段:

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 &); 

這需要一個非const參照COMPLEX對象作爲第二個參數。當你嘗試寫

cout << a + b << endl; 

a + b值是一個右值,不是左值,因爲它是由函數operator +返回的值。在C++中,你不能綁定到右值的引用,因爲那麼你可以做壞事情是這樣的:

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

這裏的問題是,如果我們可以參考c結合由a + b返回,那麼臨時對象我們可以使用該引用對該對象進行更改。但這沒有任何意義 - a + b是表達式的值,而不是實際的對象。

這是在這裏發生的同樣的問題。您的operator <<函數不能將a + b作爲第二個參數,因爲a + b是一個右值。

爲了解決這個問題,你可以改變operator <<採取const參考複雜:

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

這工作,因爲在C++中可以綁定到右值常量引用。這樣做的理由是,如果你有一個常量引用到臨時,你不能讓這種臨時對象的任何變化,所以與參考結合a + b上面的例子不再是一個問題。

通常,任何重載操作,取入其類型是不修改實例應該通過const引用利用其參數的類的其他實例的參數。這適用於諸如operator =,operator +等等,因爲它避免了這個問題。

0

重寫cout聲明

cout << "something" << (complex1 + complex2) << "\n"; 
+0

耶!我早些時候嘗試過,而且確實有效。但我想知道我們是否可以執行類似cout << 1 + 2的操作;那麼這是否也適用於上述情況? – kny8mare 2011-02-05 20:28:14

+0

哎呀!試過你的方法..仍然沒有工作。結果是像以前一樣被強制轉換爲int。我可以做這項工作的唯一方法是將結果分配給COMPLEX類型的第三個對象,然後cout。 – kny8mare 2011-02-05 20:38:10

1

您的運營< <需要採取一定的基準,否則,編譯器將無法施放臨時COMPLEX類型(從相加結果)的成一個非const引用,並可能尋找一個替代運算符< <來調用。

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

要了解操作員力學的休息,你只需要看一看在operator precedence table

0

你的問題是,運營商< <運營商+之前總是被調用。您提供重載的事實不會改變這一點。

在另一方面,你一般不宜混合計算的I/O反正(也許只是節省一些打字),因爲這使得它很難看到你的計算順序。