输入输出是每一种编程语言必不可少的局部,c++ 也不例外,上面咱们就来阐明 c ++ 的规范输入输出的前世今生。
1. 首先说一下 iostream 和 iostream.h 的区别
#include<iostream> // 这个就是 1998 年标准化当前的规范头文件, 应用时须要应用申明命名空间 std
#include<iostream.h> // 这个就是标准化以前的头文件, 外面的函数以及类都是全局的
iostream 是当初 C ++ 中规定的规范,目标在于使 C ++ 代码用于移植和混合嵌入时不受扩展名.h 的限度,防止因为.h 而造成的额定的解决和批改。
iostream 蕴含的基本功能和对应的 iostream.h 雷同,iostream 中定义的内容都在命名空间 std 中,而 iostream.h 是为了对 c 语言进行兼容,所以将规范输入输出性能都定义在全局空间中,他们的应用办法也是不一样的,另外举荐间接应用 iostream,毕竟 iostream.h 是很多年前的老物件了,规范 c ++ 中曾经明确不实用了,当前有可能被淘汰。
留神:在标准化的过程中,库中有些局部的细节被批改了,所以旧头文件和新头文件中的实体不肯定齐全对应
这里看一下他们应用上的不同:
#include<iostream.h>
或者是
#include<iostream>
using namespace std;
可见但凡要应用规范 c ++ 输入输出,都须要加上 using namespace std。
2. 输入输出流关系梳理
要弄清楚 c ++ 的输入输出流,必须要从源头找起,从安装文件外面找出输入输出流相干的头文件,大略列一下,相干头文件有以下这些:
- istream,能够看到 istream 头文件是申明了 basic_istream 模板类
- ostream,ostream 头文件是申明了 basic_ostream 模板类
- iostream,iostream 只是申明了一个 istream 对象和三个 ostream 对象,这一点前面会阐明
- iosfwd,iosfwd 头文件外面申明了所有输入输出类的模板类的一个实例
- fstream,fstream 外面申明了 basic_filebuf 模板类、basic_ifstream 模板类、basic_ofstream 模板类
- iomainip,iomainip 外面申明了一些带参数的操纵算子
- sstream,sstream 外面申明了 basic_stringbuf 模板类、basic_istringstream 模板类、basic_ostringstream 模板类
- streambuf,streambuf 外面申明了 basic_streambuf 模板类
下面说到 iosfwd 对输入输出的类模板做了实例化,咱们截取一段代码,如下:
/// Base class for @c char streams.
typedef basic_ios<char> ios; // 根底类
/// Base class for @c char buffers.
typedef basic_streambuf<char> streambuf;
/// Base class for @c char input streams.
typedef basic_istream<char> istream;
/// Base class for @c char output streams.
typedef basic_ostream<char> ostream;
/// Base class for @c char mixed input and output streams.
typedef basic_iostream<char> iostream;
/// Class for @c char memory buffers.
typedef basic_stringbuf<char> stringbuf;
/// Class for @c char input memory streams.
typedef basic_istringstream<char> istringstream;
/// Class for @c char output memory streams.
typedef basic_ostringstream<char> ostringstream;
/// Class for @c char mixed input and output memory streams.
typedef basic_stringstream<char> stringstream;
/// Class for @c char file buffers.
typedef basic_filebuf<char> filebuf;
/// Class for @c char input file streams.
typedef basic_ifstream<char> ifstream;
/// Class for @c char output file streams.
typedef basic_ofstream<char> ofstream;
/// Class for @c char mixed input and output file streams.
typedef basic_fstream<char> fstream;
为了叙述不便,后续咱们间接应用以上实例类来代指模板类,上面用一张图阐明这些类之间的关系:
箭头代表继承的关系,而后相应的 buf 后缀的类是同一列的其余类应用的缓冲区类。
以 istream,ostream,iostream 三者为例,看一下具体的继承关系,如下:
template<typename _CharT, typename _Traits>
class basic_istream : virtual public basic_ios<_CharT, _Traits>;
template<typename _CharT, typename _Traits>
class basic_ostream : virtual public basic_ios<_CharT, _Traits>;
template<typename _CharT, typename _Traits>
class basic_iostream
: public basic_istream<_CharT, _Traits>,
public basic_ostream<_CharT, _Traits>;
能够看到 basic_istream 和 basic_ostream 都是虚继承于 basic_ios,basic_iostream 是继承于 basic_istream 和 basic_ostream,留神这里继承于 basic_ios 的时候之所以要用虚构继承,是为了避免多重继承时,多个父类共用基类产生二义性。
注:所谓二义性是指 basic_iostream 类对象会产生两个 basic_ios 对象,用了虚继承后,就只会产生一个 basic_ios 对象,从而防止了二义性。
说到这里,我想问一下,有多少人最开始接触 iostream 的时候首先应用的是 cin 和 cout 呢,其实通过 iostream 头文件,咱们能够看到,咱们罕用的 cin 对象就是 istream 的一个实例,而 cout 则是 ostream 的实例,规范 c ++ 中还申明了 ostream 的另外两个实例 cerr、clog。