流状态和c++的异常处理

出来混迟早是要还的系列(误)。

在学习OpenGL的时候,遇到了一些语言上的障碍(可以读懂,但是不知道具体用法),因此补了一下相关知识。

源代码如下:

std::ifstream vShaderFile;

vShaderFile.exceptions(std::ifstream::failbit|std::ifstream::badbit);

try
{
    //...这里没有throw语句
}
catch(std::ifstream::failure e)
{
    std::cout<<"ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ"<<std::endl;
}

先从简单的讲起,也就是try......catch......语句。

我们知道,对于一些异常(exception) c++自己不会处理,当运行程序遇到异常的时候也只会崩溃(crash),因此我们需要手动去捕获异常(当然这建立在你知道哪个代码块可能会出现异常的情况),手动捕获异常就需要这个try......catch......语句。

它们的分工是这样的:try负责检测语句块,catch负责去捕获这个异常,这就好比catch告诉try,你去检测一下你那边的语句块有没有异常,有的话告诉我,我来搞定,没有的话就别来烦我。。。另外值得一提的是,在try语句块中,发生异常的语句之后的语句都不会被执行到,只会直接跳转到catch语句。

还有需要说明的就是throw了,程序语句中的错误必须显式地被抛出,try语句才能检测到,再然后进一步被catch捕获。

因此形成了throw......try......catch体系。

但是很奇怪的是,我们发现上面的语句块里面并没有出现throw,这是为什么呢?

原因出现在更上面的ios::exceptions函数中。下面开始讲exceptions函数。


查找c++ reference中的ios::exceptions函数,给出来的定义是这样的

std::ios::exceptions
get (1)    iostate exceptions() const;
set (2)    void exceptions (iostate except);
Get/set exceptions mask
The first form (1) returns the current exception mask for the stream.

The second form (2) sets a new exception mask for the stream and
clears the stream's error state flags (as if member clear() was called).

根据定义,我们可以知道重载一的返回值是当前流的异常掩码( exceptions mask )状态。

重载二对当前流设置一个新的状态掩码,并且清除流的错误状态标志(类似于调用了clear()函数)。当流本身的状态与当前的状态掩码一致的时候就会抛出异常这就是为什么try语句中没有throw语句却还能正常抛出错误的原因了)。值得注意的是,默认的状态掩码是goodbit,此时流出错的话并不会主动抛出异常。

还有需要补充的就是rdstate()函数和(重载一) exceptions()函数之间的区别了。

我们知道这两个函数的返回值是iostate的值,iostate有四种情况:badbit, failbit,eofbit, goodbit。十进制值分别是4 2 1 0,因此这两个函数的返回值就看这四个状态标记位(iostate)的情况。我们知道exceptions()函数返回当前流设置的异常掩码(exceptions mask)状态,而rdstate()返回当前流本身的状态。

 

以上。

给出几个参考博客:

[1]C++ I/O库流状态标志位  (这里要注意他的failbit badbit goodbit eofbit的值是错误的,我写的才是对的)

[2]ios::exceptions()函数

[3]ios::exceptions - C++ Reference

[4]C++异常处理,从入门到精通

[5]C++流(stream)总结

 

posted @ 2019-09-19 11:24  jckcoenf  阅读(1028)  评论(0编辑  收藏  举报