当前课程知识点:基于Linux的C++ > 第十讲 操作符重载 > 10.12 流操作符重载(三) > LinuxCPP1012
我们可以看到这样一个文件
输入输出的例子
我们将以前实现的那个点对象
输出到我们的文件里
第一件事情
我们要构造一个输出文件流对象
这个输出文件流对象从属于类ofstream
我们就ofstream 输出流对象叫ofs
然后我用一个单参数的
构造函数构造它
这个参数就是那个输出文件的文件名
就把那个文件名传进去
其它都是缺省的
我去构造它 传的就是这个文件名
在“CPP”目录下面有一个“filestream”
后面有一个“data.txt”
我们就把这个文件名和这个输出流
给挂在一块 如果你缺省构造
你没有传这个文件名
那么在这个ofs输出流构造完毕之后
可以调用它的成员函数open
传文件名参数进去
打开那个对应的文件 也可以
然后我们定义了Point2D、Point3D
的两个点对象
然后ofs << pt2d;ofs << pt3d
就把这两个点对象流到了文件里
这两个操作一做完
这两个点对象的数据
就被我们写入到了外部磁盘文件
做完了以后 你调用成员函数close
关闭这个文件
这个输出文件流就和那个文件
它的关系就被打断了
然后那个文件就被关闭了
那个资源就会被销毁 被释放
我们程序结束 很简单吧
就按照这个格式定义ofstream类的一个对象
然后把它跟一个文件挂在一块
然后就像标准的流操作一样
就可以访问那个文件了
多方便哪 输入其实也一样
你看 我们接下来的这个代码
就是把这两个点对象从文件中
再给它读出来 我们就定义ifstream
ifs(ifstream类的一个对象)
这是输入文件流对象
仍然是和这个文件给挂接在一起
然后我们定义这两个对象
Point2D、Point3D的两个对象
然后我们ifs >> pt2d >> pt3d
OK 搞定了 是不是特方便
当然肯定是特别方便
记住当这个流操作完毕之后
仍然不要忘了close 要关闭这个文件
看我们Point2D和Point3D的具体实现
我们需要看一下两个类
到底是怎么输出的
刚才那个例子我已经谈到过了
当我实现这个点数据输出的时候
我当时输出的格式和输入的格式
实际上是不一样的 那个不成
你如果格式不一样 你把它输出出去
你再输入回来 你读不出来了
所以这两个格式本身必须是匹配的
如果你“(a,b)”格式输出这两个字段
你必须按照这个模式
来输出这个Point2D的
当你输入的时候也必须按照这个模式来
给你数据就是小括号对里面
两个数据中间用逗号分割开的
这样一个点 二维的点
你要从前往后读
一个一个读 去分析它的
正常情况下
如果你知道确定的一个格式
把它格式控制的那些字符跳过以后
就直接去读那两个整数 其实是可以的
这个没问题 是可以的
但是如果你的文件中
出现了一些特定的意外
比如中间封装了一些空格
或者是一些其它什么特殊的情况
可能就不是那么好办
所以有的时候为了保证
我们读取一点问题都没有
我们可能需要一个字符、一个字符去读入
然后去分析 然后去重构每一个整数
这个效率当然可能是低的
但是我们能够保证输入这个动作
是一个字符、一个字符分析过来的
中间如果有一些字符出现了一些小意外
但并不影响我们数据结果的话
那么这个问题
我们可以在这个函数内部实现的时候
就能够把它解决掉
这是非常重要的一个实现 麻烦
但是能够解决一些额外的问题
如果你觉得那个文件一定不出问题
你可以不实现得这么复杂
就直接一个量、一个量去输出、输入
那么实际上写的代码比这个短很多
这个函数内部的具体实现我就不解释了
对于同学们来讲
仔细琢磨一下其实就可以了
Point3D类的实现也一样
只不过这里面是三个字段
特别需要注意的一个地方
就是我们的数据持久化
持久化是什么
持久化就是将一个数据
保存到我们的外部磁盘文件上
这个就能够保证我们的数据
在整个程序存续之外
它仍然能够存在
那这个数据不就持久化了嘛
就长时间存在 就这个意思
假设我们考虑像这样的一个编程任务
它里面有一些数据我需要把它流入流出
为了提升这个程序的效率
正常情况下面我们只在有必要的时候
才进行数据的持久化
你比如说我从磁盘上
把这个数据读到内存里
然后我操作了几次 这个数据就变了
当我这个程序退出的时候
这个数据就应该写回到磁盘文件上去
如果我把那个数据
从磁盘上调到内存里面运行了一段时间
但是这个数据我从来都没改
当我这个程序退出的时候
这个数据就不需要写回到
我们的磁盘文件上去
就说这个数据没有被更新
不能朝磁盘文件上去写
这是非常明确的一个地方
要不然怎么叫持久化呢
这一点是你需要考虑的
问题是我们在重载我们的流操作的时候
我们是以ostream类的一个引用
来传递os这个参数的 它是ostream
它是输出流类的 它不是文件流类
明白这个概念吗 就说我重载这个流
不仅仅适应于我们的文件流
它还适应于一般的流 包括字符串流
那么 这个数据
它到底是从文件中流进来的
还是从其它的一个普通流对象中流进来的
对这个数据是否更新
也就是它和磁盘文件中的那个数据
是不是完全一致
它们的影响是不一样的
当你重载这两个流操作符的时候
在内部必须能够处理这个问题
而处理这个问题的最好的方案
就是需要运行期的型式信息
那个是我们下一讲将会讨论的一个地方
虽然它并不是我们下一讲的重点
它只是我们下一讲要讨论
泛型编程的时候
引入的一个额外的知识点
但是它仍然是相当重要的一个知识点
是解决我们这个问题
最重要的一个技术细节
-1.1 提纲
-1.2 程序设计的基本概念
-1.3 简单C/C++程序介绍
-1.4 程序设计的基本流程
-1.5 基本语法元素
-1.6 程序设计风格
-1.7 编程实践
-第一讲 C/C++基本语法元素--编程实践提交入口
-2.1 提纲
-2.2 结构化程序设计基础
-2.3 布尔数据
-2.4 分支结构
-2.5 break语句
-2.6 循环结构
-2.7 编程实践
-第二讲 程序控制结构--编程实践提交入口
-3.1 提纲
-3.2 函数声明、调用与定义
-3.3 函数调用栈框架
-3.4 编程实践
-第三讲 函数--编程实践提交入口
-4.1 提纲
-4.2 算法概念与特征
-4.3 算法描述
-4.4 算法设计与实现
-4.5 递归算法(一)
-4.6 递归算法(二)
-4.7 容错与计算复杂度
-4.8 编程实践
-第四讲 算法--编程实践提交入口
-5.1 提纲
-5.2 库与接口
-5.3 随机数库(一)
-5.4 随机数库(二)
-5.5 作用域与生存期
-5.6 典型软件开发流程(一)
-5.7 典型软件开发流程(二)
-5.8 编程实践
-第五讲 程序组织与开发方法--编程实践提交入口
-6.1 提纲
-6.2 字符
-6.3 数组(一)
-6.4 数组(二)
-6.5 结构体
-6.6 编程实践
-第六讲 复合数据类型--编程实践提交入口
-7.1 提纲
-7.2 指针基本概念
-7.3 指针与函数
-7.4 指针与复合数据类型(一)
-7.5 指针与复合数据类型(二)
-7.6 字符串
-7.7 动态存储管理(一)
-7.8 动态存储管理(二)
-7.9 引用
-7.10 编程实践
-第七讲 指针与引用--编程实践提交入口
-8.1 提纲
-8.2 数据抽象(一)
-8.3 数据抽象(二)
-8.4 链表(一)
-8.5 链表(二)
-8.6 链表(三)
-8.7 链表(四)
-8.8 函数指针(一)
-8.9 函数指针(二)
-8.10 抽象链表(一)
-8.11 抽象链表(二)
-8.12 编程实践
-第八讲 链表与程序抽象--编程实践提交入口
-9.1 提纲
-9.2 程序抽象与面向对象
-9.3 类类型
-9.4 对象(一)
-9.5 对象(二)
-9.6 类与对象的成员(一)
-9.7 类与对象的成员(二)
-9.8 类与对象的成员(三)
-9.9 继承(一)
-9.10 继承(二)
-9.11 继承(三)
-9.12 多态(一)
-9.13 多态(二)
-9.14 编程实践
-第九讲 类与对象--编程实践提交入口
-10.1 提纲
-10.2 四则运算符重载(一)
-10.3 四则运算符重载(二)
-10.4 关系与下标操作符重载
-10.5 赋值操作符重载(一)
-10.6 赋值操作符重载(二)
-10.7 赋值操作符重载(三)
-10.8 赋值操作符重载(四)
-10.9 赋值操作符重载(五)
-10.10 流操作符重载(一)
-10.11 流操作符重载(二)
-10.12 流操作符重载(三)
-10.13 操作符重载总结
-10.14 编程实践
-第十讲 操作符重载--编程实践提交入口
-11.1 提纲
-11.2 泛型编程概览
-11.3 异常处理机制(一)
-11.4 异常处理机制(二)
-11.5 运行期型式信息(一)
-11.6 运行期型式信息(二)
-11.7 模板与型式参数化
-11.8 题外话:术语翻译
-11.9 泛型编程实践(一)
-11.10 泛型编程实践(二)
-11.11 泛型编程实践(三)
-11.12 泛型编程实践(四)
-11.13 泛型编程实践(五)
-11.14 泛型编程实践(六)
-11.15 泛型编程实践(七)
-11.16 泛型编程实践(八)
-11.17 泛型编程实践(九)
-11.18 泛型编程实践(十)
-11.19 编程实践
-第十一讲 泛型编程--编程实践提交入口
-12.1 提纲
-12.2 程序执行环境(一)
-12.3 程序执行环境(二)
-12.4 程序执行环境(三)
-12.5 程序执行环境(四)
-12.6 输入输出(一)
-12.7 输入输出(二)
-12.8 文件系统
-12.9 设备
-12.10 库(一)
-12.11 库(二)
-12.12 makefile文件(一)
-12.13 makefile文件(二)
-12.14 makefile文件(三)
-12.15 编程实践
-第十二讲 Linux系统编程基础--编程实践提交入口
-13.01 提纲
-13.02 进程基本概念
-13.03 信号
-13.04 进程管理(一)
-13.05 进程管理(二)
-13.06 进程管理(三)
-13.07 进程间通信(一)
-13.08 进程间通信(二)
-13.09 进程间通信(三)
-13.10 进程间通信(四)
-13.11 进程池
-13.12 编程实践
-第十三讲 进程编程--编程实践提交入口
-14.1 提纲
-14.2 线程基本概念
-14.3 线程管理(一)
-14.4 线程管理(二)
-14.5 线程管理(三)
-14.6 线程管理(四)
-14.7 线程同步机制(一)
-14.8 线程同步机制(二)
-14.9 C++11线程库(一)
-14.10 C++11线程库(二)
-14.11 C++11线程库(三)
-14.12 C++11线程库(四)
-14.13 C++11线程库(五)
-14.14 编程实践
-第十四讲 线程编程--编程实践提交入口
-15.1 提纲
-15.2 Internet网络协议
-15.3 套接字(一)
-15.4 套接字(二)
-15.5 编程实践
-第十五讲 网络编程--编程实践提交入口