C++基础知识六

一、虚析构
当使用delete释放一个父类指针时(父类引用),不管指向的是父类对象还是子类对象,都只会调用父类的析构。

当使用多态特性时,如果子类中有需要析构释放的资源,为了避免内存泄漏就需要把父类的析构函数设置为虚函数。

当父类的析构函数为虚函数时,子类的析构会自动覆盖它而不用比较它们的名字,当通过父类或引用来释放子类对象时会自动调用子类的析构函数。

二、文件流
C++把对文件的操作封装到了类中。
ifstream 输入文件流
ofstream 输出文件流
fstream 输入/输出文件流

1、打开文件
    使用类的构造函数或open成员函数打开文件,它们的参数一样。
    void open( const char *filename, openmode mode );
    filename: 文件路径
    mode:
        ios::app 追加输出 
        ios::ate 当已打开时寻找到EOF 
        ios::binary 以二进制模式打开文件 
        ios::in 为读取打开文件 
        ios::out 为写入打开文件,
        ios::trunc 覆盖存在的文件 

    ifstream:默认mode
        ios::in 为读取打开文件,文件不存在则打开失败
    ofstream: 默认mode
        ios::out 为写入打开文件,文件不存在则创建
        ios::trunc 清空存在的文件
    fstream: 默认mode
        ios::in 为读取打开文件
        ios::out 为写入打开文件
2、关闭流 close成员函数
    与标准C的fclose和系统的close功能一样。

3、格式化输入输出
    可以完全按照cout/cin的使用方式来读写格式化文件。
    在读写类或结构时候可以重载输入输出运算符(<</>>)来提高效率,重载方法与cout/cin的一样。
    还可以使用一些格式标志来设置输入输出流的格式,通过flags(), setf(), 和 unsetf() 三个函数来控制。
    详细格式志请查看帮助手册。

4、二进制读写
    istream &read( char *buffer, streamsize num );
    功能:以二进行格式读取数据
    buffer:存储数据的缓冲区
    num:想要读取的字节数
    注意:返回值并不是成功读取到的字节数,而是流对象的引用,可以通过输入流的成员函数gcount获取成功读取到的字节数。

    ostream &write( const char *buffer, streamsize num );
    功能:以二进制格式写入数据
    buffer:待写入的数据的首地址
    num:要写入的字节数
    注意:返回值不是成功写入的字节数,通过流的good成员函数判断是写入成功。

5、随机读写
    istream &seekg( off_type offset, ios::seekdir origin );
    功能:以偏移称加基础位置设置文件位置指针

    istream &seekg( pos_type position );
    功能:以绝对位置设置文件位置指针

    pos_type tellg();
    功能:获取输入流的文件位置指针

    ostream &seekp( off_type offset, ios::seekdir origin );
    ostream &seekp( pos_type position );
    pos_type tellp();
    功能:同上

    origin: 基础位置
        ios::beg
        ios::cur
        ios::end

三、类型信息
typeid 用于获取数据的类型信息,返回type_info类型临时对象。

使用前要加头文件typeinfo,type_info对象成员函数name可以获取到基本的缩写,自定义类型的名字及名字的长度,
以P开头的是指针类型。

type_info对象还支持== !=运行符,能分辨出两种个数据是否是同一种类型。

如果用于判断父子类的指针或引用,它不能准备分辨出实现的对象类型,但如果父类有虚函数,就可以分辨出来。

四、异常处理
在C++中当代码出现问题时,不能通过返回值和errno反映的,而是随机可以返回一个未知的数据来表示错误。

抛异常:
    throw 数据(基本类型|自定义类)。
    注意:不能抛出局部对象的指针或引用,因为当异常抛出后函数就执行结束了,函数的栈内存会被释放,如果返回局部对象的指针或引用则返回的是野指针或悬空引用。
    最好抛临时对象,而上层代码用const引用捕获。
异常捕获:
    注意:如果抛出的异常没有被捕获,程序就会停止。
    try{
        可以抛出异常的代码
    }
    catch(const 类型1& 变量名)
    {
        处理异常,如果无法处理可以向上层代码继续抛出异常。
    }
    catch(const 类型2& 变量名)
    {

    }
    ...

    异常捕获是从上到下匹配,只要合适就算匹配成功,并不是择优匹配。
    如果异常类型可能是父子类,那么在捕获时要先子类后父类。

函数的异常声明:
    在声明函数时可以函数的末尾声明此函数可能抛出的异常。
    void func(void) throw(类型1,类型2,...);

    1、如果不写异常声明则表示该函数什么类型的异常都可能抛出。
    2、如果抛出声明以外的异常类型,则该异常无法捕获,程序肯定会死亡,因此声明异常时要慎重。
    3、throw() 表示什么异常都不会抛出

五、C++标准库异常
C++标准库异常定义了常见的异常,可以直接使用,同时C++标准库中也使用这套异常。
这些异常类都有一个what成员函数,里面记录了异常产生的原因。

class Error
{
    int errno;
    char* msg;
    Error(const Error& that) {}
    void operator=(const Error& that) {}
public:
    Error(const char* str="未知类型错误!",int errno=-1):errno(errno)
    {
        msg = new char[strlen(str)+1];
        stdrcpy(msg,str);
    }
     ~Error(void)
    {
        delete[] msg;
    }
    const char* msg(void)
    {
        return msg;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值