std::cin、std::cout、std::cerr和std::endl在C++裡的真實面目
C++輸入和輸出
在C++裡std::cin、std::cout、std::cerr和std::endl分別是標準輸入、標準輸出、標準錯誤輸出和重新整理緩衝區並換行,它們都在名稱空間std中,那麼它們真實面目是什麼?我們先來看一段程式碼:
#include
這段程式碼很簡單,就是輸出“Hello world!”和“error”,那麼這段程式碼的底層原理是?我們先來看一下std::cout在標準庫中的定義:
#ifndef _LIBCPP_HAS_NO_STDOUTextern _LIBCPP_FUNC_VIS ostream cout;extern _LIBCPP_FUNC_VIS wostream wcout;#endif……typedef basic_streambuf
從以上程式碼我們可以看出std::cout是一個類basic_stream
basic_ostream& operator<<(bool __n);basic_ostream& operator<<(short __n);basic_ostream& operator<<(unsigned short __n);basic_ostream& operator<<(int __n);basic_ostream& operator<<(unsigned int __n);basic_ostream& operator<<(long __n);basic_ostream& operator<<(unsigned long __n);basic_ostream& operator<<(long long __n);basic_ostream& operator<<(unsigned long long __n);basic_ostream& operator<<(float __f);basic_ostream& operator<<(double __f);basic_ostream& operator<<(long double __f);basic_ostream& operator<<(const void* __p);basic_ostream& operator<<(basic_streambuf
充分證實了我們猜想,<<其實是成員函式operator<<並且返回值是basic_ostream&,到這裡我們就可以看出std::cout << “Hello World!”其實是basic_ostream例項變數cout呼叫成員函式operator<<輸出字串“Hello World!”並返回basic_ostream&。
那麼std::endl是不是某個類的例項呢?我們看看std::endl在標準庫的定義:
template
從程式碼裡可以看出,std::endl其實是一個函式模板,呼叫該函式會將一個換行符“\n”放入緩衝區,並重新整理緩衝區,最後返回basic_ostream&。到這裡我們終於明白std::cout << “Hello World!” << std::endl;的含義了,basic_ostream例項變數cout呼叫成員函式operator<<輸出字串“Hello World!”,返回basic_ostream&並繼續呼叫成員函式operator<<輸出換行符並重新整理輸出緩衝區。
現在我們很容易想到std::cerr和std::cout應該差不多,區別則是std::cerr是標準錯誤輸出,將資訊輸出到標準錯誤流。std::cerr定義如下:
extern _LIBCPP_FUNC_VIS ostream cerr;extern _LIBCPP_FUNC_VIS wostream wcerr;extern _LIBCPP_FUNC_VIS ostream clog;extern _LIBCPP_FUNC_VIS wostream wclog;
最後我們看看std::cin到底是什麼玩意,先來看下下面這段程式碼:
#include
程式碼很簡單,就是想透過標準輸入輸入名字,並儲存在變數name中。有了上面的經驗,我們很容易想到std::cin應該是某個類的例項變數,而>>則是類的成員函式。std::cin的定義如下:
#ifndef _LIBCPP_HAS_NO_STDINextern _LIBCPP_FUNC_VIS istream cin;extern _LIBCPP_FUNC_VIS wistream wcin;#endif……typedef basic_streambuf
從程式碼中可以看出std::cin是類basic_istream
basic_istream& operator>>(basic_streambuf
不出我們所料>>確實是成員函式operator>>並返回basic_istream&,那麼這段程式碼std::cin>>name就很容易理解了,basic_istream
到這裡std::cout、std::cin、std::cerr和std::endl的含義終於真相大白了!
往期推薦
C++11很吊的新特性!std::function
C++裡std::enable_shared_from_this是幹什麼用的?
C++ mutable關鍵字如何使用?