第01讲 运算符重载
9.1 运算符重载
C++语言允许程序员重新定义已有的运算符,使其能按用户的要求完成一些特定的操作,这就是所谓的运算符重载。
运算符重载与函数重载相似,其目的是设置某一运算符,让它具有另一种功能,尽管此运算符在原先C++语言中代表另一种含义,但他们彼此之间并不冲突。C++会根据运算符的位置辨别应使用哪一种功能进行运算。
C++内部任何运算都是通过函数来实现的。运算符重载的实质就是函数重载。
在实现过程中,首先把指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参,然后根据实参的类型来确定需要调用的函数,这个过程是在编译过程中完成的。
运算符的重载形式有两种:重载为类的成员函数和重载为类的友元函数。
运算符重载为类的成员函数的语法形式如下:
<函数类型> operator <运算符>(<形参表>)
{
<函数体>;
}
运算符重载为类的友元函数的语法形式如下:
friend <函数类型> operator <运算符>(<形参表>)
{
<函数体>;
}
例9.1
P186 <<、>>和++运算符重载实例
插入符函数的一般形式为:
ostream &operator << (ostream & 函数的流, 类名&对象名)
{ …… //函数代码
return函数的流;
}
提取符函数的一般形式为:
istream &operator >> (istream & 函数的流, 类名&对象名)
{ …… //函数代码
return函数的流;
}
例9.2
例9.3
1.函数调用方式;
2.直接使用运算符
例9.4
第02讲 流类库
运算符和友元运算符的区别 P190
如果运算符所需的操作数,尤其是第一个操作数希望进行隐式类型转换,则该运算符应该通过友元来重载。
另一方面,如果一个运算符的操作需要修改类对象的状态,则应当使用类运算符,这样更符合数据封装的要求。但参数是使用引用还是对象,则要根据运算符在使用中可能出现的情况来决定。
friend complex operator + (形参1,形参2)
{ ……//函数体定义 }
关键字friend把 complex operator + (形参1,形参2)说明成类的友元,使得它能够访问类complex 的私有数据。
形参可以都是对象或者对象的引用;
形参也可以一个为对象一个为引用,这要视具体问题而定。
例9.5
例9.6
9.2 流类库
9.2.1流类库的基础类
在C++中,输入输出操作是由“流”来处理的。所谓流,它是C++的一个核心概念,数据从一个位置到另一个位置的流动抽象为流。
当数据从键盘或磁盘文件流入到程序中时,这样的流称为输入流,把输入数据来自的地方称为“源”
当数据从程序中流向屏幕或磁盘文件时,这样的流称为输出流,把接收输出数据的地方称为“目标”
当流被建立后就可以使用一些特定的操作从流中获取数据,如输入操作;也可向流中添加数据,如输出操作。
从流中获取数据的操作称为提取操作,向流中添加数据的操作称为插入操作。
执行输入、输出的类体系叫做流类
提供这个流类实现的系统库叫做流类库
流类库C++针对流的特点,构造了功能强大的输入输出流库
ios类用来提供一些关于对流状态进行设置的功能,它是一个虚基类,其它类都是从这个派生而来
但streambuf不是ios类的派生类,在类ios中只是有一个指针成员,指向streambuf类的一个对象。streambuf类是用来为ios类及其派生类提供对数据的缓冲支持。
缓冲,是指系统在主存中开辟一个专用的区域用来临时存放输入输出信息,这个区域称为缓冲区。有了缓冲以后,输入输出时所占用的CPU时间就大大减少了,提高了系统的效率。因为只有当缓冲区满时,或当前送入的数据为新的一行时,系统才对流中的数据进行处理,称为刷新。
itream和ostream类均是ios的公有派生类,前者提供了从流中提取数据的有关操作,后者则是提供了向流中插入数据的有关操作。
iostream类是itream和ostream类公有派生的,该类并没有提供新的操作,只是将itream和ostream类综合在一起,提供一种方便。
流类库P194
为了方便用户对基本输入输出流进行操作,只要在程序中包含头文件iostream,就可以使用C++提供的四个预定义的标准流对象:cin、cout、cerr和clog,它们都是std名称空间的流对象。
cin是istream类的对象,用处理可定向得标准输入,即键盘输入。
cout是ostream类的对象,用处理标准输出,即屏幕输出。
cerr和clog都是ostream类的对象,用来处理标准出错信息,并将信息显示在屏幕上。
在这四个标准流对象中,除了cerr不支持缓冲(发送给它的内容立即被输出到屏幕,并且不能被重定向到其它地方),其余三个都带有缓冲区。
标准流通常使用提取运算符“>>”和插入运算符“<<”来进行输入输出操作的,而且系统还会自动地完成数据类型的转换。
一种具体的物理设备,比如说键盘联接起来。
C++的流类库预定义的4个流所联接起的具体设备为:
cin 与标准输入设备相联接
cout 与标准输出设备相联接
cerr 与标准错误输出设备相联接(非缓冲方式)
clog 与标准错误输出设备相联接(缓冲方式)
9.2.2默认输入输出格式控制
9.2.3使用ios_base类
1. ios_base类简介
ios_base类派生ios类,ios类又是istream类和ostream类的虚基类。
2.直接使用格式中控制
3,使用成员函数
第03讲 文件流
9.3 文件流
为方便用户对文件的操作,C++提供了文件操作的文件流库
ifstream类是从istream类公有派生而来,用来支持从输入文件中提取数据的各种操作
ofstream类是从ostream公有派生而来,用来实现把数据写入到文件中的各种操作。
fstream类是从iostream类公有派生而来,提供从文件中提取数据或把数据写入到文件的各种操作。
filebuf类从streambuf类派生而来,用来管理磁盘文件的缓冲区,应用程序中一般很少涉及到该类。
文件流P199
C++中文件输入/输出的基本过程
1.在程序中要包含头文件fstream.h。
2.创建一个流。
ifstream iFile;
ofstream oFile;
fstream ioFile;
3.将这个流与文件相关联,即打开文件。
void open(const char filename,int mode,int access);
4.文件的读写操作。
5.关闭文件。
iFile.close();
oFile.close();
参照P201【例9.10】演示重载流运算符的例子
P197
【例9.7】演示使用标志位的例子
【例9.9】演示文件流的概念
文件流输出流的open函数,即打开文件
void open(const char filename,int mode,int filebuf::openprot);
文件打开方式 | 说 明 |
---|---|
Ios_base::in | 以输入方式打开文件,即读文件(ifstream类对象默认方式) |
Ios_base ::out | 以输出方式打开文件,即写文件(ofstream类对象默认方式) |
Ios_base ::app | 以添加方式打开文件,新增加的内容添加在文件尾 |
Ios_base ::ate | 以添加方式打开文件,新增加的内容添加在文件尾,但下次添加时则添加在当前位置 |
Ios_base ::trunc | 如文件存在就打开并清除其内容,如不存在就建立新文件 |
Ios_base ::binary | 以二进制方式打开文件(默认为文本文件) |
Ios_base ::nocreate | 打开已有文件,若文件不存在,则打开失败 |
Ios_base ::noreplace | 若打开的文件已经存在,则打开失败 |
文件名访问模式打开方式
文件流filebuf::openport 共享方式,默认的方式
filebuf::sh_none 独占方式,不允许共享
filebuf::sh_read 允许读共享
filebuf::sh_write 允许写共享
关闭文件时,系统把该文件相关联的文件缓冲区中的数据写到文件中,保证文件的完整,收回与该文件相关的内存空间,可供再分配,把磁盘文件名与文件流对象之间的关联断开,可防止误操作修改了磁盘文件。如又要对文件操作必须重新打开。
三个文件流类各有一个关闭文件的成员函数 :
void ifstream::close();
void ofstream::close();
void fstream::close();
使用很方便,如:
iFile.close();
oFile.close();
iofile.close();
对一个流对象进行输入、输出操作时,可能会产生错误,一般在进行文件的操作时,需要进行相应的错误判断
if(cin.good())cin>>data;
表示没有错误和文件没有结束时,才从文件获取数据
处理错误的成员函数及功能如下:
成员函数 | 功 能 |
---|---|
bad() | 如果进行非法操作,返回true,否则返回false |
clear() | 设置内部错误状态,如果用缺省参量调用则清除所有错误位 |
eof() | 若文件读到末尾,返回true,否则返回false |
good() | 如果没有错误条件和没有设置文件结束标志,返回true,否则返回false |
fail() | 与good()相反,操作失败返回false,否则返回true |
Is_open() | 若流对象是否成功地与文件关联,返回true,否则返回false |
文件存取操作的综合实例
设计一个student类,用这个类作为数据类型产生一个向量。为简便起见,本例只要求输入学生学号和成绩,将这些信息存入向量中,然后将向量的内容写入文件stud,txt中,最后将向量和文件的内容进行比较,验证存取文件的正确性。
使用VC设计工程文件student,它含有头文件student.h和源文件student.cpp。
参照P204~207
1.头文件student,h
2.源文件student.cpp
3.运行示范