原因是:
-
+,-,*等返回不了引用,比如+運算符,可以如下重載(為了簡單,假設A 只有int x;int y)
A operator+(A a,A b) {A sum; sum.x=a.x+b.x; sum.y=a.y+b.y; return sum; }
分析不能用引用的原因: 函數傳入了兩個參數a,b,並且+只能傳入兩個參數(c++不允許自己創造運算符),這樣就限定了和sum不能作為參數傳入,所以sum只能是一個函數里的臨時變量,但是臨時變量在函數結束時是要銷毀的,那么函數調用玩,sum就沒有了, 如果返回引用,引用源都已經沒有了,還怎么引用,引用哪里的東西呢??
所以不能引用。
-
<<,>>可以返回引用,而且不返回引用也是編譯不過的,貌似是c++的要求。可以不用引用試一試,有的編譯器會出來一個ios_base.h文件,就是想告訴你用引用。
返回引用也是可以解釋的。 比如還是上面的A類型,如下
ostream& operator<<(ostream& out, const A& a) { out<<A.x<<' '<<A.y<<endl; retrun out;}
能返回引用,首先是因為out是作為參數傳入的,不是函數的臨時變量,函數結束時它仍然存在,這樣就可以引用了。 再者,返回引用效率高,不用拷貝一個新的,直接返回它自己。 而且,返回引用有助於連着調用。比如cout<<a<<b<<c<<d,為什么可以連着寫?其實<<也是函數,為什么我們平時的函數一般不能連着寫?如a.xx().xx().xx.()這樣調用三個xx()。這也體現了引用的作用。 對於cout<<a<<b<<c<<d;就是
operator<<(operator<<(operator<<(operato<<(cout,a),b),c),d);
從左到右先執行cout<<a執行完了后返回cout的引用,就是cout本身,那么原式變為cout<<b<<c<<d; 緊接着這行cout<<b執行完再次返回cout........這樣就把a,b,c,d依次作用到了cout,我們於是看到abcd連續輸出了。
如你所說,cout<<a<<b<<c<<d;譚浩強說,先執行cout<<a,返回一個輸出流對象(引用),然后這個新的cout對象(引用)又執行<<b,然后又返回一個新的cout對象(引用),直到輸出完成。每輸出一次,就返回一個新的輸出流對象(引用),那每次輸出流對象cout有啥不同。
一般可以認為第一次執行完cout直接將a輸出到了屏幕,cout本身沒有變化,然后執行b......
但是具體情況不是這樣的。這要看c++的IO具體是怎么設計的。執行一次cout<<a並不一定直接將a輸出到屏幕,而是將a轉到IO的緩沖區,具體什么時候將a輸出到屏幕要看系統什么時候有時間和c++的IO具體是怎么實現的。 系統掌握着消息隊列,每次從里面抽取一條消息執行,因為CPU效率很高,我們感覺程序是連續運行的,其實不連續。對於多核處理器來說可以發生真實的同時執行幾個程序。
要強制系統將數據輸出到屏幕上,可以“刷新”一下,比如用cout<<endl;就是打一個換行,再刷新緩沖區,刷到屏幕上。
對於評論區的兩點,解釋一下:
-
重載<<流輸出運算符,我是用於一個自定義類與ostream類,不是重載<<的移位運算等,不用做其他用法。 在我的編譯器上不通過(VS2012和DEV c++都編譯不通過)
-
我舉得例子有錯誤,為了簡便直接寫的,現在發現是錯的。因為都是A的對象相加,如果有兩個參數,那么應該是友元函數,frined ......, 如果一個參數,可以聲明為成員函數。
至於為什么返回引用也正常,這是由於:
“函數返回的臨時變量是放在堆棧上的,所以返回來后如果你沒有調用其他的函數,那么這個臨時變量在依然保存在堆棧中,是可以被引用的。
因為這時堆棧並沒有被破壞。但是一旦調用其他函數后堆棧被破壞了,那個返回值就沒有用了”摘自“正心修身齊家治國平天下”的百度空間,可以看一下。
即使這樣編譯器也會給警告(WARNING),不建議這么寫
===================以上摘自百度https://zhidao.baidu.com/question/917635728677386659.html