• C++中异常处理


    看了下thinking in c++ v2 中的 exception handling, 这里简单总结下C++语言层面exception handling理解

    1 .  throw,  try , catch

    throw expression ; 这是在程序普通地方用的, expression总是有一个类型的, 也就是说可以抛出任意一个 type 的 object;

    throw ; 是在 catch 语句里面使用的, 把接收到的object再次抛出,   当然在catch中也可以再抛出任意type的异常

     1 #include <iostream>
     2 using namespace std;
     3 int main ()try{
     4     try {
     5         throw 5;
     6     } catch (...){
     7         cout << "catch exception" << endl;
     8         throw 'c';
     9     }
    10     cout << "after try,catch" << endl;
    11     return 0;
    12 }catch (int e){
    13     cout << "catch for main" << " e = " << e << endl;
    14 }catch (char e){
    15     cout << "catch for main ,any exception type" << " e = " << e << endl;
    16 }

    一个测试程序, 第10行不会被执行到, 可以看到3行,如何try上整个函数体,第8行在catch中再次抛出另一个类型 object;

    2.   标准库中定义的异常

    标准库中异常相关的有两个头文件 <exception> , <stdexcept>   这两个头文件都很小型, 里面有一些 类定义, 函数指针, 函数, 类的成员函数都只有声明, 我猜想这两个头文件(应该是所有的c++标准库都在一个动态/静态库中)

    <exception>中定义了 exception, bad_exception  exception是库中所有异常类的基类, 有一个 virtual member   :  const char* what() const;  bad_exception从exception中派生, 这里先不做解释, 参见库中说明http://www.cplusplus.com/reference/std/exception/bad_exception(而且没明白有什么用)  另外声明了  set_expected,  set_terminated

    <stdexcept>中定了两组异常类,  标准库在使用, 自己的程序也可以使用  logic_error, runtime_error  基类exception的构造函数是没有参数的, 而这两组类的构造函数有一个参数 string& what_arg , 异常的文字描述,  what()会返回它

    3.  function-level try block ;   exception specification

    在thinking in c++中提到, 标准库之所以没有在函数声明中使用exception specification, 是因为标准库中都是模板, 而对模板参数代表的未知类型, 不知道会抛出什么样的异常, 所以标准库只在文档中提出可能会抛出什么样的异常

    1 void function () throw (int , exception);
    2 void function2 () throw();
    3 void function3 () ;

    我暂时觉得这个没什么用, 我还没用过, 而且有些函数并不能确定它会抛出哪些类型的异常, 有可能它调了其它函数, 而其它函数又被替换, 不完全在你的控制之下,   上面第2行表示function2不会抛出异常, 第3行表示可能抛可能不抛

    关于function-level try block  除了1中代码中提到的那种, 还可以如下这种使用 (19行), 在派生类的constructor中捕获基类和成员对象构造函数 抛出的异常, 从下面这段代码的各种执行还可以看出, 基类constructor先于成员constructor执行, 然后才是自己的constructor.  另外要注意在Derived构造函数的异常处理中处理了, 在main中那行(32行)依然会抛出异常, 如果在main中没有捕获处理, 就直接退出main了

     1 #include <iostream> 
     2 using namespace std;
     3 class Base{
     4 public :
     5         Base(){
     6             cout << "Base default constructor" << endl;
     7             throw int(2);
     8         }
     9         Base(int i){
    10             cout << "Base constructor" << endl;    
    11 //            throw i;
    12         }
    13         ~Base(){
    14             cout << "Base destructor" << endl;
    15         }
    16 };
    17 class Derived : public Base{
    18 public :
    19         Derived(int i) try:  Base(i){
    20             cout << "Derived constructor" << endl;
    21         } catch (int e){
    22             cout << "exception caught in Derived e = "  << e << endl;
    23         } catch (...){
    24             cout << "unknown exception caught in Derived" << endl;
    25         }
    26 private :
    27         Base base;
    28 };
    30 int main ()try{
    31     try{
    32         Derived  derivced(6);
    33     } catch (int e){
    34         cout << "catch after derivedi e = " << e << endl;
    35     }
    36 }

       

  • 相关阅读:
    yii2框架随笔9
    yii2源码学习笔记(五)
    yii2源码学习笔记(四)
    yii2源码学习笔记(三)
    yii2源码学习笔记(二)
    yii2源码学习笔记
    学习yii2.0框架阅读代码(一)
    (转)OAuth 2.0授权协议详解和流程
    (转)JavaScript 中对变量和函数声明的“提前(hoist)”
    JavaScript 中的算术运算
  • 原文地址:https://www.cnblogs.com/livingintruth/p/2469658.html
Copyright © 2020-2023  润新知