zoukankan      html  css  js  c++  java
  • C++中的异常处理(上)

    1,C++ 内置了异常处理的语法元素 try ... catch ...;

        1,try 语句处理正常代码逻辑;

        2,catch 语句处理异常情况;

        3,try 语句中的异常由对应的 catch 语句处理;

           1,代码示例:

    1 try
    2 {
    3     double r = divide(1, 0);  // divide() 函数里面产生除 0 异常,于是 divide() 函数就会将这个异常抛出到调用的地点,这个地点正好在 try 语句块中,其会将捕捉到的异常扔给下面的 catch 代码块,catch 代码块就可以将除 0 异常捕捉到,于是打印 Divided by zero ...;
    4 }
    5 catch(...)
    6 {
    7     cout << "Divided by zero ..." << endl;
    8 }

             

    2,C++ 通过 throw 语句抛出异常信息:

        1,代码示例:

     1 double divide(double a, double b)
     2 {
     3     const double delta = 0.000000001;
     4     double ret = 0;
     5            
     6     if( !((-delta < b) && (b < delta)) )
     7     {
     8            ret = a / b;
     9     }
    10     else
    11     {
    12            throw 0;  // 0 这个字面值常量代表当前的异常元素,表示产生除 0  异常; 异常元素可以是一个值、一个对象、一个字符串等; 扔出异常元素后,divide() 就会立即返回到调用点;
    13      }
    14            
    15      return ret;
    16 }

        2,C++ 中 throw 这个新的关键字就是用来仍出异常元素的,我们简称为“异常”,每一个异常都需要被 catch 语句来处理;

          

    3,C++ 异常处理分析:

        1,throw 抛出的异常必须被 catch 处理:

           1,当前函数能够处理异常,程序往下执行;

           2,当前函数无法处理异常,则函数停止执行,并返回;

               1,返回是异常返回,和正常返回不一样;

               2,异常产生后的函数返回是没有返回值的;

        2,未被处理的异常会顺着函数调用栈向上传播,知道被处理为止,否则程序将停止执行;

        3,C++ 异常处理初探编程实验:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 double divide(double a, double b)
     7 {
     8     const double delta = 0.000000000000001;
     9     double ret = 0;
    10     
    11     if( !((-delta < b) && (b < delta)) )
    12     {
    13         ret = a / b;
    14     }
    15     else
    16     {
    17         throw 0;  
    18     }
    19     
    20     return ret;
    21 }
    22 
    23 int main(int argc, char *argv[])
    24 {    
    25     try
    26     {
    27         double r = divide(1, 0);  // 扔出异常后,divide() 自身没有 try...catch...,不能处理异常,所以 divide() 这个函数就会立即的停止并且带着异常元素返回到调用点,而 main() 函数中当也没有try...catch... 语句时,异常向上传播,main() 已经是第一个函数了,则导致整个程序异常停止,编译器显示:terminate called after throwing an instance of 'int',已放弃;当 main() 中包含 try...catch... 语句时,程序正常打印:Divided by zero...;
    28             
    29         cout << "r = " << r << endl;
    30     }
    31     catch(...)  // “...” 表示见下分析;
    32     {
    33         cout << "Divided by zero..." << endl;
    34     }
    35     
    36     return 0;
    37 }

          

    4,同一个 try 语句可以跟上多个 catch 语句:

        1,catch 语句可以定义具体处理的异常类型;

        2,不同类型的异常由不同的 catch 语句负责处理;

        3,try 语句中可以抛出任何类型的异常;

           1,try 语句块用于放置可能产生异常的代码,工程里面一般都习惯将正常功能逻辑代码放在 try 语句块中,然后后面跟上多个 catch 语句;

           2,可以是一个 int、字符串、对象;

        4,catch(...) 用于处理所有类型的异常;

           1,一般情况作为最后出场的语句块;

        5,任何异常都只能被捕获(catch)一次;

           1,只要被 catch 一次,其它的 catch 就没有捕获机会了;

       

    5,异常处理的匹配规则:

        1,示意图:

     

        2,try 语句块中直接通过 throw 扔出整型异常;

        3,扔出后发现是在 catch 语句块中,然后这个异常就会进行 catch 语句块的匹配;

        4,从上向下严格匹配每个 catch 它所需要捕获的异常类型;

        5,匹配 catch 语句块所标识的类型时,是不会进行任何的类型转换的;

        6,如果说不能够严格匹配上,那么当前的异常没有被捕获,当前的函数就会立即的停止执行,并且带着这个异常沿着函数调用栈顺序的返回;

       

    6,异常类型匹配编程实验:

     1 #include <iostream>
     2 #include <string>
     3 
     4 using namespace std;
     5 
     6 void Demo1()
     7 {
     8     try
     9     {   
    10         throw 'c';
    11     }
    12     catch(char c)
    13     {
    14         cout << "catch(char c)" << endl;
    15     }
    16     catch(short c)
    17     {
    18         cout << "catch(short c)" << endl;
    19     }
    20     catch(double c)
    21     {
    22         cout << "catch(double c)" << endl;
    23     }
    24     catch(...)  // 当把它放到其它 catch 语句块前面的时候,编译器显示:error: '...' handler must be the last handler for its try block;
    25     {
    26         cout << "catch(...)" << endl;
    27     }
    28 }
    29 
    30 void Demo2()
    31 {
    32     throw "D.T.Software;  // 两个分开执行的;
    33     throw string("D.T.Software");
    34 }
    35 
    36 int main(int argc, char *argv[])
    37 {    
    38     Demo1();
    39     
    40     try
    41     {
    42         Demo2();  // 认为它可能产生字符串异常,所以将它放到了这里;                 
    43     }
    44     catch(char* s)
    45     {
    46         cout << "catch(char *s)" << endl;
    47     }
    48     catch(const char* cs)  // 没有这个 catch 语句块时,第一个异常执行后编译器显示:terminate called after throwing an instance of 'char const *';
    49     {
    50         cout << "catch(const char *cs)" << endl;
    51     }
    52     catch(string ss)
    53     {
    54         cout << "catch(string ss)" << endl;
    55     }
    56     
    57     return 0;
    58 }

       

    7,小结:

        1,C++ 中直接支持异常处理的概念;

        2,try ... catch ... 是 C++ 中异常处理的专用语句;

        3,try 语句处理正常代码逻辑,catch 语句处理异常情况;

        4,同一个 try 语句可以跟上多个 catch 语句;

        5,异常处理必须严格匹配,不进行任何的类型转换;

  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/dishengAndziyu/p/10919819.html
Copyright © 2011-2022 走看看