C 輸出運算子過載,為什麼要返回引用才能實現連續輸出?返回物件不可以實現連續輸出嗎?

時間 2021-06-03 01:53:01

1樓:石大頭

其他答主說得很好了。題主應該更進一步體會值語義和物件語義的區別,物件語義天生是不支援拷貝的。比如說Person laowang("laowang");拷貝一下難道代表有兩個老王嗎

2樓:

回答最長的那個我覺得太複雜了。

為什麼要返回引用其實很簡單,輸出運算子「<<」是乙個運算子,跟算術運算子「+」一樣,有著相應的規則,例如「+」運算子要求是左右都有乙個運算物件,運算子使用後返回表示式的值,所以你只能寫成1+2,不能寫成12+或者+12,也可以寫成1+2+4,這樣1+2運算完後返回3,3再繼續作為下乙個「+」的左側運算物件,繼續表示式3+4的運算。

同樣地,輸出運算子「<<」要求左側必須是乙個輸出流ostream物件,右側是乙個待寫到ostream物件的值,這個運算子運算完畢後返回左側物件,也就是ostream,這樣的話cout<

自己過載時,不引用輸出流,返回的就不是輸出運算子「<<」規定的左側物件,比如返回是乙個值,然後變成『』值<

要真正理解什麼是運算子,不要書上說到運算子「+」就只有「1+2」這種意識,要想一下左側和右側要求是什麼,返回什麼結果。這樣才能很好的理解運算子過載。

3樓:藍形參

如果吧operator << 換成F,鏈式表示式可以理解為這樣:F(

F(F(

std::

cout

,'x'

),'y'

,'z'

);// cout << 'x' << 'y', 'z'

可以看到,我們要做的是實現F函式

如果F返回的是std::ostream&,那麼我們只需要讓F的第乙個引數接收std::ostream&即可,接收的和返回的都是左值。

如果F返回的是std::ostream,而不是引用的話,F的第乙個引數必須考慮左值(具名變數std::cout)和右值(F的返回值)的情況。

由於non-const不能繫結右值,所以在C++98中,鏈式表達無法成立。

std::cout << 'x' << 'y'成功 ^失敗:因為ostream&不能接收ostream型別的右值

除非你修改C++標準庫中ostream的實現,要麼允許拷貝構造(比如通過引用計數方式),要麼通過加上mutable/const修飾,並修改F的定義成const std::ostream &operator << (const::ostream &x, const Type &t);

在不修改ostream類的情況下,C++11中接下來有兩個選擇:

為左值和右值各過載乙份:

那麼,對每乙個型別,我們修改其operator << 為

std::ostream operator << (std::ostream &x, const Type &treturn std::move(x); }

std::ostream operator << (std::ostream &&x, const Type &treturn std::move(x); }

把F的第乙個引數也改成物件本身而不是引用

ostream& operator << (ostream &, const Type &);

必須全部改成ostream operator << (ostream, const Type &);

這樣一來會有個問題

std::cout << 'x';//編譯錯誤:因為std::cout不能拷貝構造

要過通過編譯你必須改成

std::

move

(std

::cout

)<<'x'<<

'y'<<

'z';

鏈式表示式是可以成立的,可是執行完了這一行,std::cout就失效了,要避免這個情況。你還得用std::cout去接收返回值

最終你得改成

std::

cout=(

std::

move

(std

::cout

)<<'x'<<

'y'<<

'z');

哪種比較麻煩?

4樓:

可以啊,就是每次都要複製乙份再析構,多浪費。

#include

class A

A(const A&)

~A()

A operator <<(int i)

};int main()

如何過載 運算子?

XZiar operator返回乙個double 或者不就夠了,使用時裡的第二個是指標自帶。不過存多維陣列的話我還是推薦扁平化 C 怎麼實現效率盡可能高地帶邊界檢查的多維陣列模板類? 果凍蝦仁 與其過載不如過載 你所需要的操作它都能滿足,而且也不失優雅。這種表達,很容易聯想到一種資料型別,那就是矩陣...

python如何實現左側的運算子過載?

Kittyhawk 先從myob 1說起,假設myob屬於Myob類,這裡我們過載了 mul class Myob def mul self val print mul 過載了 mul 後我們就可以順利實現myob 1,結果是列印出 mul 但如果把兩者換一下位,1 myob,就會報錯了。這是因為1...

c語言中復合運算子的存在意義是什麼?

zr scat 有些復合運算可能翻譯成一條機器指令,比如n 1可以直接翻譯為帶桶型移位器的賦值。語義上定義二元運算或者三元運算並不需要過多解讀,就跟數學上定義各種算符的涵義類似,理解並合理使用即可。 單純是因為c誕生之初的組合語言有類似 之類的指令罷了 對於現在稍微做點最起碼優化的編譯器,a a b...