ostream & operator << (ostream & output, const ClassType & object)
{
output << ...
...
return output;
}
|
- 返回類(lèi)型為什么是引用?
- 第一個(gè)參數(shù)為什么用引用?
- 第二個(gè)參數(shù)為什么又是const引用?
一個(gè)函數(shù)的定義,從返回類(lèi)型到形參列表,我們都要有清晰的認(rèn)識(shí)和理解,才能明白應(yīng)該怎樣編寫(xiě)這個(gè)函數(shù)。
- 返回引用是為了使得返回結(jié)果為左值,相當(dāng)于一個(gè)獨(dú)立對(duì)象的作用,使我們可以做連續(xù)輸出的操作,例如
1 | cout << object1 << object2 <<endl;
|
注意:返回引用要慎用,尤其是不能返回局部變量的引用,一般返回引用是針對(duì)當(dāng)前對(duì)象返回 *this 或者返回const 類(lèi)型的引用。
- 第一個(gè)參數(shù)之所以為引用,首先是避免了IO對(duì)象的復(fù)制,注意:這里不是刻意避免IO對(duì)象的復(fù)制,而是IO對(duì)象不可復(fù)制或賦值,所以這里必須用引用類(lèi)型,不能傳遞流類(lèi)型。由此我們應(yīng)該知道,既然IO對(duì)象不支持復(fù)制或賦值,則一方面流對(duì)象不能存儲(chǔ)在vector或其它容器中(只有支持復(fù)制的類(lèi)型才可以存儲(chǔ)vector等容器中);另一方面,形參或返回類(lèi)型都不能為流類(lèi)型(因?yàn)樯婕皬?fù)制),如果要傳遞或返回IO對(duì)象,則必須傳遞指向該流對(duì)象的指針或引用。此外,可能你會(huì)注意,為什么第二個(gè)參數(shù)為const類(lèi)型,那第一個(gè)參數(shù)為什么不是const呢?ostream之所以為非const類(lèi)型,很明顯,寫(xiě)入流會(huì)改變流的狀態(tài),所以使用非const
- 第二個(gè)形參為const類(lèi)型的引用,關(guān)于這樣形參的好處,在博文“美妙的const”中有詳細(xì)闡述。首先對(duì)于要輸出的類(lèi)類(lèi)型,避免了對(duì)象的復(fù)制;其次,一般輸出一個(gè)對(duì)象是不應(yīng)該改變?cè)搶?duì)象的,故為const;再者,const引用可以使得傳遞參數(shù)更為靈活,例如,這樣定義,我們就可以使用同一個(gè)定義來(lái)傳遞輸出const和非const對(duì)象。關(guān)于const與非const對(duì)象的問(wèn)題,參見(jiàn)博文美妙的const.
- 說(shuō)到這里,順便提一下重載輸入流操作符,在輸入流操作符函數(shù)定義中,第二個(gè)參數(shù)則必須為非const,因?yàn)檩斎肓饕淖冊(cè)搶?duì)象。
綜上,這里面的每個(gè)細(xì)節(jié)都是必須的,不能更改。
值得一提的是,重載流操作符函數(shù)必須為類(lèi)的非成員函數(shù)。原因是,如果設(shè)定為成員函數(shù),則做操作數(shù)必然為該類(lèi)的類(lèi)對(duì)象,用法就變成了
這顯然與我們所要的相悖。說(shuō)到這里就順便說(shuō)一下為類(lèi)設(shè)計(jì)重載操作符時(shí)候應(yīng)該將其設(shè)置為類(lèi)的成員函數(shù)還是非成員函數(shù),下面是我的總結(jié),僅供參考:
- 必須為成員函數(shù):5個(gè):賦值(=),下標(biāo)符([ ]),調(diào)用符(( )),成員訪問(wèn)箭頭符(->),“轉(zhuǎn)換函數(shù)”。前兩個(gè)比較常用,調(diào)用符重載即函數(shù)對(duì)象,箭頭符不太常見(jiàn),指針類(lèi)型類(lèi)會(huì)用到;轉(zhuǎn)換函數(shù)則是用在“從”類(lèi)類(lèi)型到內(nèi)置類(lèi)型的轉(zhuǎn)換時(shí)用到(標(biāo)準(zhǔn)轉(zhuǎn)換為內(nèi)置類(lèi)型的轉(zhuǎn)換,類(lèi)類(lèi)型的轉(zhuǎn)換則分為“從”類(lèi)類(lèi)型的轉(zhuǎn)換和“到”類(lèi)類(lèi)型的轉(zhuǎn)換)
- 建議為成員函數(shù):4個(gè):復(fù)合賦值操作符,自增,自減,解引用;這幾個(gè)操作符是與類(lèi)類(lèi)型緊密相連的或改變對(duì)象狀態(tài)的操作符。
- 必須為非成員函數(shù):1種:流操作符(輸入、輸出)
- 建議為非成員函數(shù):4種:等等操作符,算術(shù)操作符,關(guān)系操作符,位操作符
到這里吧,一個(gè)流操作符函數(shù)嘮叨了這么多,都是基礎(chǔ),類(lèi)似上面這些基礎(chǔ)知識(shí),在《C++ primer》中都有涉及,而且分析的很好。
下面說(shuō)一點(diǎn)自己的感受吧,在學(xué)習(xí)一個(gè)新東西的時(shí)候,我們不能局限課本,有時(shí)間還是看看那些經(jīng)典的書(shū)籍,可以少走很多彎路,我體會(huì)最深的一點(diǎn)就是當(dāng)時(shí)學(xué)習(xí)C++的“拷貝構(gòu)造函數(shù)”、“析構(gòu)函數(shù)”、“重載賦值運(yùn)算符”時(shí)糾結(jié)了很長(zhǎng)一段時(shí)間,記得那時(shí)往往析構(gòu)的時(shí)候編譯器總是彈框,還有什么深拷貝淺拷貝的問(wèn)題,后來(lái)寫(xiě)了很多程序廢了好大勁才覺(jué)得有點(diǎn)眉目,總結(jié)出來(lái)是如果類(lèi)中有指針成員,就要注意上面的那些函數(shù)問(wèn)題,是否需要定義自己的拷貝構(gòu)造和重載賦值運(yùn)算符等等。
后來(lái)看了《C++ primer》,當(dāng)看到“復(fù)制控制”那一章時(shí),記得當(dāng)時(shí)真有種捶胸頓足的感覺(jué),明明前人都總結(jié)的“經(jīng)驗(yàn)三法則”在那里擺著,我卻不知道,如果早點(diǎn)看就不至于走那么多彎路了,而且自己總結(jié)出來(lái)的總有點(diǎn)山寨的感覺(jué),所以經(jīng)典很重要,我們必須要學(xué)會(huì)“站在巨人肩膀上”,這樣也可以提高效率,加快進(jìn)步。