cpp拾遗——流

0. cpp 对 带缓存的输入输出的改进

c printf scanf 的缺点:

  1. 无法检查类型,如 print("%s", a); a可以是 int 类型,也能编译通过。
  2. 无法扩展,如 希望 自定义一个 %v 输出某个结构体类型。

cpp的流系统解决了如上问题

cpp的流系统如下

常用头文件,和提供的功能

  • iostream  包含了对输入输出流进行操作所需的基本信息。
  • fstream  用于用户管理的文件的I/O操作。
  • strstream  用于字符串流I/O。
  • stdiostream  用于混合使用C和C + +的I/O机制时,例如想将C程序转变为C++程序。
  • iomanip  在使用格式化I/O时应包含此头文件。

缓存IO
和c标准库一样,不过cpp的更方便,不仅输出缓存,输入也缓存,所以可以提供很多操作
cout,遇到 endl时,输出到标准输出
cerr,输出到标准错误,无缓存
clog,输出到标准错误,有缓存

1. 流对象分析

打开 iostream,知道预先定义了 多个流对象

   60   extern istream cin;       /// Linked to standard input
   61   extern ostream cout;      /// Linked to standard output
   62   extern ostream cerr;      /// Linked to standard error (unbuffered)
   63   extern ostream clog;      /// Linked to standard error (buffered)

搜索 ostream 定义,发现其为 basic_ostream

  137   /// Base class for @c char input streams.
  138   typedef basic_istream<char>       istream;
  139
  140   /// Base class for @c char output streams.
  141   typedef basic_ostream<char>       ostream;

打开 ostream ,知道 basic_ostream的定义

   57   template<typename _CharT, typename _Traits>
   58     class basic_ostream : virtual public basic_ios<_CharT, _Traits>

basic_ostream的声明有点怪,有点像声明了 basic_ostream 两次,但其实是这样的

  // basic_ostream 继承 basic_ios,
  // 由于 basic_ios 是模板类,所以 basic_ostream也是模板类,
  // 在 basic_ostream 内声明 类 sentry
  template<typename _CharT, typename _Traits>
  class basic_ostream : virtual public basic_ios<_CharT, _Traits>
  {
        class sentry;
        friend class sentry;
  };
  // 完成 sentry 的声明
  // basic_ostream<_CharT, _Traits> :具体化一种 basic_ostream类,毕竟只有模板类具体化后才能使用内部成员
  template <typename _CharT, typename _Traits>
  class basic_ostream<_CharT, _Traits>::sentry
  {
  };

说明下类中声明类

class A{
    public:
    class B;
};

class A::B {
    public:
        int a;
};

class B{
    public:
        int a;
};

int main()
{
    B a;
    a.a = 1;
    A::B a2;
    a2.a = 2;

    return 0;
}

类有namespace的效果,所以根据namespace的本质,类中声明类,翻译为c语言为

struct A_B {
   int a;
};
struct B {
   int a;
};

继续分析basic_ostream,可以发现 类模板更好的风格,是用 typedef 对形参类型 进行重命名

   60     public:
   61       // Types (inherited from basic_ios):
   62       typedef _CharT                    char_type;
   66       typedef _Traits                   traits_type;

basic_ostream 主要实现流操作<<
其父类 basic_ios 实现缓存。
其父类 ios_base 定义很多 flag。

posted on 2022-06-08 13:45  开心种树  阅读(45)  评论(0编辑  收藏  举报