乐趣区

关于c++:c标准输入输出流关系梳理

输入输出是每一种编程语言必不可少的局部,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。

退出移动版