说明一下,我用的是g++7.1.0编译器,标准库源代码也是这个版本的。
本篇文章讲解c++标准IO的底层实现结构,以及cin和cout的具体实现。
在看本文之前,建议先看一下之前的一篇文章,至少要知道标准IO里面各个类之间的关系:
1. 标准IO的底层结构
通过通读c++标准IO的源代码,我总结出了它的底层实现结构,如图:
它分为三层结构:外部设备、缓冲区、程序,说明如下:
- 外部设备是指键盘、屏幕、文件等物理或者逻辑设备;
- 缓冲区是指在数据没有同步到外部设备之前,存放数据的一块内存;
- 程序就是我们代码生成的进程了。
下面我们首先以输出一个字符为例来看一下它的实现过程,这个过程是由ostream::put
函数完成,下面就探究一下put函数的具体实现。
1.1 先探探底层实现的底
小贴士:tcc是指template cc,cc是c++实现文件的后缀,加上t表示是模板的实现,所以tcc就是一个模板的实现文件,用于跟其他非模板的实现文件区分开来。
在ostream.tcc
中找到put函数的实现代码:
template<typename _CharT, typename _Traits>
basic_ostream<_CharT, _Traits>&
basic_ostream<_CharT, _Traits>::
put(char_type __c)
{
sentry __cerb(*this);
if (__cerb)
{
ios_base::iostate __err = ios_base::goodbit;
__try
{
const int_type __put = this->rdbuf()->sputc(__c);
if (traits_type::eq_int_type(__put, traits_type::eof()))
__err |= ios_base::badbit;
}
__catch(__cxxabiv1::__forced_unwind&)
{
this->_M_setstate(ios_base::badbit);
__throw_exception_again;
}
__catch(...)
{ this->_M_setstate(ios_base::badbit); }
if (__err)
this->setstate(__err);
}
return *this;
}
以输出一个字符为例,put函数是调用了缓冲区基类basic_streambuf
的sputc
成员函数,而sputc
成员函数实现如下:
int_type