ostream operator <<
C++有一個名稱manipulator(操控器),是專門用來操空stream的物件,只會改變輸入或格式化輸出的解釋方式。
用於ostream的操控器並不會憑空造出輸出資料,有些操控器會引發立即的動作,如果「刷新(flush)output緩衝區」
或「輸出換行符號'\n'」,等等的動作。在學習C++中對於endlflush並不會陌生,接下來要說明他們到底是什麼樣
子呢?在標題檔ostream中,可以查到下列的程式:
// MANIPULATORS
template<class _E, class _Tr> inline
	basic_ostream<_E, _Tr>&
		__cdecl endl(basic_ostream<_E, _Tr>& _O)
	{_O.put(_O.widen('\n'));
	_O.flush();
	return (_O); }
_CRTIMP inline basic_ostream<char, char_traits<char> >&
	__cdecl endl(basic_ostream<char, char_traits<char> >& _O)
	{_O.put('\n');
	_O.flush();
	return (_O); }
_CRTIMP inline basic_ostream<wchar_t, char_traits<wchar_t> >&
	__cdecl endl(basic_ostream<wchar_t,
		char_traits<wchar_t> >& _O)
	{_O.put('\n');
	_O.flush();
	return (_O); }

	return (_O); }
template<class _E, class _Tr> inline
	basic_ostream<_E, _Tr>&
		__cdecl flush(basic_ostream<_E, _Tr>& _O)
	{_O.flush();
	return (_O); }
_CRTIMP inline basic_ostream<char, char_traits<char> >&
	__cdecl flush(basic_ostream<char, char_traits<char> >& _O)
	{_O.flush();
	return (_O); }
_CRTIMP inline basic_ostream<wchar_t, char_traits<wchar_t> >&
	__cdecl flush(basic_ostream<wchar_t,
		char_traits<wchar_t> >& _O)
	{_O.flush();
	return (_O); }
綠色字體請參考前一篇文章,而且以下的程式將省略以上綠色字體。

在此說明widen(...),flush(),put(char c):

widen(char c):用來將一個原生(native)字元集內「型別為char」的字元,轉換為「locale所用字元集」
內對應字元。也就是說此函式來「拓寬」一個字元,即使結果亦為char型別也無妨。若與國際化議題無關時
可以不需在意。主要的目是在於國際化的議題。

flush():刷新output stream的緩衝區,將緩衝區的內容寫至輸出裝置中(如螢幕)

put(char c):將引數c寫至stream,傳回stream
template<class _E, class _Tr> inline basic_ostream<_E, _Tr>&  ???(basic_ostream<_E, _Tr>& _O)
inline basic_ostream<char, char_traits<char> >& ???(basic_ostream<char, char_traits<char> >& _O)
inline basic_ostream<wchar_t, char_traits<wchar_t> >&  ???(basic_ostream<wchar_t, char_traits<wchar_t> >& _O)
不管是endlflush都會有一個template的版本、char特化版本及wchar_t特化版本,但其實若不理國際化的議題時
,char特化版本已經夠用,所以接下來只討論char特化的版本。所以現在簡化為:
inline basic_ostream<char, char_traits<char> >&  endl(basic_ostream<char, char_traits<char> >& _O)
{	_O.put('\n');	_O.flush();	return (_O); 	}
inline basic_ostream<char, char_traits<char> >&  flush(basic_ostream<char, char_traits<char> >& _O)
{	_O.flush();	return (_O); 			}
在前一篇文章中提到basic_ostream<char, char_traits<char> >ostream是一樣的,所以上式可變為:
inline ostream&  endl(ostream& _O)
{	_O.put('\n');	_O.flush();	return (_O); 	}
inline ostream&  flush(ostream& _O)
{	_O.flush();	return (_O); 			}
那清楚endlflush是什麼嗎?是一個函式,函式具有一個參數,型態為ostream&,而回傳值ostream&。
而當在operator<<中使用endlflush時,會呼叫那一類型的operator<<呢?以下:
	ostream& operator<<(ostream& (__cdecl *_F)(ostream&))
	{return ((*_F)(*this)); }

_F是一個函式指標,指向函式,函式具有一個型態ostream&的參數及回傳值型態為ostream&endlflush正是
這一類的函式。假設程式為:cout<<endl; 這個程式同等為:cout.operator<<(endl); 所以對照上式的型式,可
得_F指向endl,並利用函式指標,執行endl的動作。flush的動同亦是一樣。
 
回目錄
Written By James On 2004/02/08 

Hosted by www.Geocities.ws

1