解開一個困擾自己多時的小問題小序今天上班的時候問了一起工作的Sidney同學一個小問題,顯然他是研究過了的,不過他當時沒有給出我答案。" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

解開一個困擾自己多時的小問題——從std::cout

系統 1988 0
<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>

解開一個困擾自己多時的小問題

小序

今天上班的時候問了一起工作的 Sidney 同學一個小問題,顯然他是研究過了的,不過他當時沒有給出我答案。這個問題著實困擾了我好長時間捏 ~~

晚上吃的小蔥蘸醬,呵呵,吃完之后氣兒順了、腦子也清醒了許多,想起這個問題沒搞定,于是順著 Sidney 同學提供的線索把問題搞明白了。

正文

問題是這樣的……

相信下面這個程序凡是會寫 C++ 程序的同仁都認得, 估計學會的第一個 C++ 程序就是它了吧:



//----------------------------------------------
//
水之真諦
// http://blog.csdn.net/FantasiaX
//----------------------------------------------

#include
<iostream><br></iostream> int main( int argc, char *argv[])
{
std::cout "Hello, World."
return 0;
}


會寫一點 C 語言的程序,于是在寫這個程序的時候就對很多東西“想當然”了。比如對于操作符“ ”,在心里一直是與 C 語言的 printf() 函數對應起來的——認為它就是封裝進了 ostream 對象中的 printf() 函數。既然是這樣,那么對于“ endl ”,自然就“想當然”地認為它是“ \n ”了。

突然有一天,在 Visual Studio 彈出的代碼自動完成窗口中發現, endl 不是一個成員變量(如果它代表一個字符,那么理應是一個字符類型的成員變量)而是一個成員函數!大腦中立刻蹦出一個解釋:或許 endl 函數的返回值是字符“ \n ”吧?可是這個答案存活了不到一秒鐘就被否定了——如果想讓一個函數執行從而得到它的返回值,應該是調用這個函數,所以寫法應該是“ std::endl() ”而不是“ std::endl ”。寫成“ std::endl ”是將函數名放在這里,并不是在調用這個函數。哈 ~~ 腦子里的概念開始互相打架了 ~~

解開一個困擾自己多時的小問題——從std::cout和endl說起

因為問題是出在了 endl 上,所以一直在查 endl 的定義——結果除了發現 MSDN 里有個 Bug 之外,一無所獲 L

MSDN 里是這樣聲名的:

template class<_elem _tr></_elem>
basic_ostream<_elem _tr>&amp; endl( basic_ostream<_elem _tr>&amp; _Ostr );</_elem></_elem>

紅色標記的地方寫錯了 :p

C++ ISO 文檔里是這樣聲名的:

template <class chart class traits><br></class> basic_ostream<chart>&amp; endl(basic_ostream<chart>&amp; os);</chart></chart>

MSDN 里模板的“寫法”根本編譯不過去,呵呵。

不過, MSDN 里的說明還是非常有用的—— Terminates a line and flushes the buffer. 可是函數的功能是“結束一行并沖洗緩沖區”,如果想執行這個功能,應該是調用這個函數、應該寫 endl() 而不是 endl 啊……看來問題又繞回去了。于是這事兒就放下了。

今天遇到高手 Sidney ,又問起了這個問題。 Sidney 是研究過這個問題的,雖然沒有給出我答案,但他提到這么一句話——“ ”操作符是被重載過的,可以接收一個函數作為參數。正好前幾天我在寫《深入淺出話回調》的時候寫過類似的程序,經 Sidney 一點撥,頓時感覺豁然開朗。很快問題的答案就找到了——

1. 先查看 <iostream></iostream> 的成員,找到一個全局對象 cout

2. 查看 cout 對象,發現它是 ostream 的一個實例

3. 查看 <ostream></ostream> 文件說明中的“ ”操作符,有 10 個重載,但是沒有可將函數作為參數的

4. 仔細想了想,會不會是從別處繼承來的呢? (操作符其實就是簡寫了的函數,完全可以當函數來對待)

5. 查看 MSDN ,發現 ostream 是由類模板 basic_ostream<char char_traits> &gt;</char> 生成的

6. 查看 basic_ostream<char char_traits> &gt;</char> 的說明,發現它也具有“ ”操作符,并且有 15 個重載。

7. 其中的一個卸載形式是——
basic_ostream& operator
說明 cout 操作符可以接受一個函數指針(函數的地址)作為參數。
這個重載正好與 endl 函數的聲名相匹配,所以 后面是可以跟著 endl 的,也就是說, cout 對象的 操作符接受到 endl 函數的地址后會在后臺調用 endl 函數,而 endl 函數會結束當前行并沖洗 buffer

最后啰嗦一句——你可能會問:不是函數指針嗎?為什么不寫“ std::cout ”而寫“ std::cout ”呢?實際上,函數名本身就代表的是函數的地址, &endl endl 的值是一樣的 J

不信你試試下面的代碼,結果與上面的一樣:

//----------------------------------------------
//
水之真諦
// http://blog.csdn.net/FantasiaX
//----------------------------------------------

#include
<iostream><br></iostream> int main( int argc, char *argv[])
{
std::cout "Hello, World."
return 0;
}



致謝

感謝 Sidney ——謝謝你對我技術上的指導。更重要的是你提醒了我學習的方面——不要只把眼睛盯在一個地方,還要看到與它相關聯的事物。還有就是要多看書,我看的書還是太少了。

博文視點就要三周年慶典了,也祝博文視點的朋友們萬事如意、工作順利、身體健康!

法律聲明 本文章受到知識產權法保護,任何單位或個人若需要轉載此文,必需保證文章的完整性(未經作者許可的任何刪節或改動將視為侵權行為)。若您需要轉載,請務必注明文章出處為 CSDN 以保障網站的權益;請務必注明文章作者為 劉鐵猛 http://blog.csdn.net/FantasiaX ),并向 liutm@beyondsoft.com 發送郵件,標明文章位置及用途。轉載時請將此法律聲明一并轉載,謝謝!




解開一個困擾自己多時的小問題——從std::cout和endl說起


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 男人电影天堂 | 瑟瑟视频在线 | 亚洲日韩欧美视频 | 欧美精品国产综合久久 | 亚洲情乱 | 一区二区三区四区国产精品视频 | 日本三级免费 | 久久久久久精 | 日韩成人免费在线 | 男女作爱免费网站 | 青草娱乐极品免费视频 | 日韩精品小视频 | 色综合a| 成人精品在线 | 91久久精品一区二区二区 | 国产αv| 91成人午夜性a一级毛片 | 亚洲影视在线观看 | 国产精品亚洲精品日韩已方 | 久久999 | 婷婷色九月综合激情丁香 | 波多野吉衣 免费一区 | 狠狠色狠狠色综合久久第一次 | 久久99热只有视精品6国产 | www.男插女b免费视频 | 成人毛片在线观看 | 日日拍夜夜嗷嗷叫视频 | 激情av在线 | 亚洲一区二区三区影院 | 综合久久亚洲 | 久操热| 日韩久久久久久 | 亚洲午夜日韩高清一区 | 国产区在线 | 欧美日韩操 | 午夜手机电影 | 欧美亚洲国产一区 | 欧美久久天天综合香蕉伊 | 亚洲午夜电影 | 手机在线观看亚洲国产精品 | 久久久91 |