标准C++(六)

一、纯虚函数和抽象类

1、纯虚函数

在虚函数声明的末尾添加=0,这种没有函数体的函数叫纯虚函数。

virtual 返回值 函数名(参数列表) = 0;
2、抽象类

成员函数中有纯虚函数的类叫抽象类,这种类不能创建对象(不能实体化)。
抽象类只能被继承、被覆盖,由子子类创建对象。
如果继承的抽象类,但没有覆盖纯虚函数,那么子类也变成了抽象类。

3、纯抽象类

所有的成员函数都是纯虚函数,这种类叫做纯抽象类。
这种类一般用于设计接口,这种类的子类被修改后,调用者不需要修改或只需要简单的修改即可继续使用。
注意:有纯虚函数的类就是一种强制的多态。

简历中可以提到的设计模式:
1、命令模式
2、回调模式
3、单例模式
4、工厂模式
5、MVC模式

C++中空的结构、类对象为什么是1字节?
结构、类中可以有成员函数
成员函数需要识别哪个对象调用的它,它需要获取到对象地址。
0字节的结构、类对象,在内存中没有存储位置也就没有了对象地址,这样就无法调用成员函数了。
所以为了让对象能正常调用成员函数,C++规定空的结构、类对象填充一个字节,为对象在内存中占据一个位置,这样对象就有地址来传递给成员函数了。

二、虚函数表

1、虚函数表指针

当一个类中定义了虚函数,那么编译器就会把这些虚函数地址存储一个表格中,然后一个指针来指向该表格,该指针会被包含到类中,因此定义了虚函数的类至少增加4字节。

2、虚函数表

虚函数表中存储的是每个虚函数的地址,当子类继承了分类后,也就继承的虚函数表指针和虚函数表。子类中的成员函数会与虚函数中的每个虚函数进行比较,如果达到覆盖的条件,子类中的函数就会替换虚函数表中的内存,这样该虚函数就被覆盖。

三、虚析构和虚构造

1、构造函数可以是虚函数吗?

如果构造函数是虚函数,那么子类的构造函数必定会覆盖父类的构造函数,当创建子类对象时,会先执行父类的构造函数,但由于实际的调用都是子类,按照多态的则此时就该调用子类的构造,而子类的构造执行前该先调用父类构造,这样就陷入了死循环,所以C++规则构造函数不可以是虚函数。

2、析构函数可以是虚函数吗?

如果析构函数是虚函数,那么子类的析构必定会覆盖父类的析构函数,当通过父类指针释放子类对象时,按照多态规则会调用子类的析构再调用父类的析构,按照正常的子类对象的释放过程也该这么执行,所以析构函数可以是虚函数。

当使用多态时,子类的析构函数有需要释放的资源,通过父类指针释放子类对象时,只会执行父类的析构,那么子类的析构函数就不会执行,可能会导致数据没有保存、资源没有释放,所以这种情况下父类的析构必须是虚函数。

四、I/O流

C++把对文件的操作封装到了类中

ofstream	对文件的写操作
ifstream	对文件的读操作
fstream		对文件的读写操作

五、打开文件

打开文件:类的构造函数open成员函数,他们的参数一样

void open(const char* filename);
void open(const char* filename,openmode mode);

mode含义

ios::app添加输出
ios::ate当已打开时寻找到EOF
ios::binary以二进制模式打开文件
ios::in为读取打开文件,文件不存在则打开失败
ios::out为写入打开文件
ios::trunc清空文件内容

默认的打开模式:

ifstream ios::in
ofstream ios::out|ios::trunc
fstream ios::in|ios::out

注意:使用 strace ./a.out 追踪打开文件时的标志。

六、文件格式读写

ifstream/ofstream/fstream 的对象使用 << >> 运算符来读写二进制数据。

注意:如果读写的对象是类对象或结构对象,建议重载它们的输入、输出运算符,即可以输入输出数据也可用于文本格式的读写。

七、随机读写

​ 设置输入流的文件位置指针
​ istream &seekg( off_type offset, ios::seekdir origin );
​ 功能:按照基础位置+偏移的方式设置文件位置指针
​ origin:
​ ios::beg 相当于C语言中的SEEK_SET
​ ios::end 相当于C语言中的EEK_END
​ ios::cur 相当于C语言中的SEEK_CUR
​ istream &seekg( pos_type position );
​ 功能:按照绝对位置设置文件位置指针
​ position:字节数

设置输出流的文件位置指针,参数同步

ostream &seekp( off_type offset, ios::seekdir origin );
ostream &seekp( pos_type position );
pos_type tellg();

功能:获取输入流的文件位置指针

pos_type tellp();

功能:获取输出流的文件位置指针

注意:为什么两套不同的设置,因为有些系统的文件位置指针的两个,分别输入和输出的,但Linux系统只有一个位置指针,因此设置那个都可以。

八、二进制读写

​ istream &read( char *buffer, streamsize num );
​ 功能:用于二进制格式读数据
​ buffer:存储数据的缓冲区
​ num:想要读取的字节数

streamsize gcount();

功能:获取最近一次读取的字节数。

ostream &write( const char *buffer, streamsize num );

功能:用于二进制格式写数据
buffer:待写入的数据的首地址
num:想写入的字节数

bool good();

功能:获取流的上一次操作是否成功,可以用于判断写入数据是否成功,也可以用于打开文件是否成功。

注意:当使用二进制格式读写类对象、结构对象时,对象中不能有指针类型的成员。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值