まず、(続けday11異常)
7、標準の例外クラス
標準の例外クラスは、パスの次のヘッダーファイルで宣言されています
C ++の例外は、言語の標準ライブラリ自体または標準の異常(Sとして知られているサブクラススローされた例外、あるタン DARD例外)。次の文は例外で、標準のすべてをキャプチャするには:
- してみてください{
- //例外文を投げるかもしれません
- } キャッチ(例外&E ){
- //ハンドル例外声明
- }
効率を向上させるために、参照を使用する理由。あなたが参照を使用しない場合は、プロセス(コピーコンストラクタを呼び出すために)オブジェクトのコピーを経験します。
クラス配置例外<例外>ヘッダ・ファイル
これは次のように宣言されます。
クラスの例外{ パブリック: 例外()スロー(); // コンストラクタの 例外(constの例外&)スロー(); // コンストラクタコピー 例外&演算子 =(constの例外&)スローは(); // 演算子オーバーロード の仮想〜例外を()スロー(); // 仮想デストラクタ 仮想 のconst のchar *どのような()constの スロー(); // 仮想関数}
これは、ここで注意しなければならないものを()関数です。どのような()関数のような、あなたは大体これは何も異常があることを伝えることができ、「何を」その名の通り、珍しい識別できる文字列を返します。しかし、C ++標準は、参照のみの値を返しますので、どのような()、様々な異なるコンパイラを達成するために、文字列の書式を指定していません。
次の図は、継承階層の例外クラスを示しています。
図:例外クラスの継承階層とそれらの対応するヘッダファイル
例外クラスを直接派生クラスで最初に見て:
例外名 | 説明 |
---|---|
logic_error | 論理エラー。 |
ランタイムエラー | 実行時エラー。 |
bad_alloc | メモリの割り当てに失敗したときに[]新しいまたは新規の使用が例外をスローします。 |
bad_typeid | typeidの操作NULLを使用して ポインタを、ポインタが仮想関数を持つクラスでは、スローされた例外をbad_typeid。 |
bad_cast | 例外をスローする場合、変換に失敗したのdynamic_castを使用します。 |
ios_base ::失敗 | Ioは、異常が発生しました。 |
bad_exception | 内部関数が例外リストをスローしたときに、関数の例外リストがbad_exception例外を宣言している場合、この例外ではありませんあなたが呼び出す場合、予期しない()関数が例外をスローし、関係なく、どのような種類の、となり、特別な例外でありますbad_exceptionの種類を交換してください。 |
logic_error派生クラス:
例外名 | 説明 |
---|---|
length_error | オブジェクトの異常から構築しようとすると、このタイプの最大長さ、例えば、ベクターのサイズ変更操作を超えます。 |
domain_error | そのような負の関数呼び出しを使用するなど、主に数学関数で使用されるレンジパラメータ誤差は、唯一の非負動作することができます。 |
out_of_range | それが範囲外です。 |
無効な引数 | 不適切なパラメータ。文字列オブジェクトの構築のビットセットを使用して、文字の文字列が0または1の時ではないとき、標準ライブラリでは、スローされます。 |
派生クラスをruntime_error:
例外名 | 説明 |
---|---|
range_error | 计算结果超出了有意义的值域范围。 |
overflow_error | 算术计算上溢。 |
underflow_error | 算术计算下溢。 |
例:
class FileError:public exception{ public: const char* what(void) const throw(){ return "文件访问失败"; } }; int main(void){ try{ //throw FileError(); char* p=new char[0xffffffff] } catch(exception& ex){//使用标准异常类,可以只写一个catch,利用多态就可以完成。 cout<<ex.what()<<endl; return -1; } }
执行结果:
注意:
自定义异常类的时候,最好继承标准异常类,并且重写what()函数,让其对标准的what()函数形成覆盖,通过多态的语法特征,在子类的what函数中处理子类异常。
8、构造函数异常
class A{ public: A(void){ cout<<"A::A()"<<endl; } ~A(void){ cout<<"A::~A()"<<endl; } }; class B{ public: B(void):m_a(new A){ FILE* fp=fopen("none.txt","r") if(!fp){ delete m_a;//释放不完整类 throw -1; } fclose(fp); } ~B(void){ delete m_a; } private: A* m_a; }; int main(void){ try{ B b; } catch(int& ex){ cout<<"异常"<<ex<<endl; return -1; } return 0; }
注意:
构造函数抛出异常之后,对象将会被不完整构造,这样的对象其析构函数不会被执行,因此在构造函数抛出异常之前,需要手动销毁所有在异常产生之前的动态资源。
9、析构函数异常
析构函数最好不要抛出异常(了解)
class A{ public: void func(void){ throw -1; } ~A(void){ throw -2; } };
int main(void){ A a; try{ a.func(); } catch(int& ex){ cout<<"异常"<<ex<<endl; return -1; } }
//因为已经跳出了catch,执行到},析构函数抛出的异常2将永远得不到捕获,最终将被系统所捕获int main(void){
INTメイン(ボイド){ 試み{ A; a.func(); } キャッチ(INT&EX){ COUT << " 異常な" << EX << ENDL; リターン - 1 ; } }
// FUNC()投げシステムが直接処理を終了しますので、異常処理に、デストラクタは、例外をスローしません
二、I/O流(了解)