Exception handling in C + + (53)

Source: Internet
Author: User

We talked about exception handling in C in the previous blog, and today we're going to deal with exception handling in the context of the. Syntax elements that are built into exception handling in C + + try ... catch ...,The try statement handles the normal code logic, the catch statement handles the exception condition, and the exception in the try statement is handled by the corresponding Catch statement。 C + + throws exception information through a throw statement, the exception thrown by the throw must be caught, the current function can handle the exception, the program continues to execute, the current function cannot handle the exception, the function stops execution and returns. Unhandled exceptions propagate upward along the function call stack until they are processed, or the program stops executing. As follows


Let's take the code as an example to analyze it.

#include  <iostream> #include  <string>using namespace std;double divide ( DOUBLE&NBSP;A,&NBSP;DOUBLE&NBSP;B) {    const double delta =  0.000000000000001;    double ret = 0;         if ( ! ( (-delta < b)  &&  (b < delta)  )     {         ret = a / b;    }     else    {        throw 0;     }        return ret;} Int main () {    try    {         double r = divide (1, 0);        cout  <<  "r = " &Nbsp;<< r << endl;    }    catch (...)     {        cout <<  "divided  by zero ... " << endl;    }    return 0;

Let's take a look at the compilation results

Let's try another 1/1.

has been correctly implemented ha. C + + This exception handling is not very convenient. The same Try statement can be followed by multiple catch statements. A catch statement can define the type of exception to be handled, and different types of exceptions are handled by different catch statements, and any type of exception can be thrown in a try statement, and the catch (...) is used to handle all types of exceptions, and any exception can only be caught (catch) at a time. Let's take a look at the matching rules for exception handling, as follows

Let's take the code as an example to illustrate

#include  <iostream> #include  <string>using namespace std;void demo1 () {     try    {        throw  0;    }    catch (char c)     {         cout <<  catch (char c)  << endl ;     }    catch (short c)     {         cout <<  catch (short c)  << endl;     }    catch (double c)     {         cout <<  catch (double c)  << endl;     }    catch (int c)     {         cout <<  "catch (int c)"  << endl;    }}void demo2 () {     throw  "D.t.software";} Int main () {    try    {         demo1 ();         //demo2 ();    }     catch (char* s)     {        cout  <<  catch (char* s)  << endl;    }     catch (CONST&NBSP;CHAR*&NBSP;CS)     {         cout <<  "catch (Const char* cs)" &NBSP;&LT;&LT;&NBSP;ENDL;&NBSP;&NBSP;&NBSP;&NBSP;}     catch (STRING&NBSP;SS)     {         cout <<  catch (STRING&NBSP;SS) &NBSP;&LT;&LT;&NBSP;ENDL;&NBsp;   }        return 0;} 

Let's see what we can print out.

We see a direct match to int at the last, because the 0 default type thrown is int, and it does not convert by default type. Let's see what Demo2 will print out.

Because the string is literal, it will match to the Const CHAR* CS, if we throw a string ("D.t.software") in the Demo2 function; see what's going to print out.

The string will be printed out. Then we can throw an exception in the Catch statement, as follows

So why do we have to re-throw exceptions in the catch statement? Exceptions caught in a catch can be re-interpreted and thrown, and used in engineering development to unify the exception type as follows

So let's take the code as an example to explain it.

#include  <iostream> #include  <string>using namespace std;void demo () {     try    {        try         {             throw  ' C ';        }         catch (int i)         {             cout <<  "Inner: catch (int i)"  < < endl;            throw i;         }        catch (...)         {             cout <<  "InnEr: catch (...) "  << endl;            throw;         }    }    catch (...)     {        cout <<  "outer:  catch (...) "  << endl;    }}/*     assumes that:  functions in the current functional third-party library, We cannot modify the source code          function name:  void func (int i)       type of exception thrown: int                         -1 ==>  parameter Exceptions                           -2 ==>  Run Exceptions                          -3 ==>  Timeout Exception */void func (Int i) {    if ( i < 0 )     {         throw -1;    }         if ( i > 100 )     {         throw -2;    }        if ( i = = 11 )     {        throw -3;     }        cout <<  "Run func ..."  << endl;} Void myfunc (int i) {    try    {         func (i);     }    catch (int i)     {        switch (i)          {            case -1:                 throw  " Invalid parameter ";                 break;            case -2:                 throw  "Runtime  exception ";                 break;            case -3:                 throw  "timeout  Exception ";                 break;         }    }}int main () {    demo ();/*         try    {         myfunc (one);     }    catch (Const char* cs)     {        cout <<  "Exception  Info:  " << cs << endl;    }*/         return 0;}

We first use the Demo function as an example to parse, throw C in the try statement in the Try statement, match to the catch (...) statement, first print out the Inner:catch (...), and then throw again. Match to the outside catch (...) statement, first print out the Outer:catch (...). Let's see the results.

We see exactly the same as our analysis. The next Func function is like a third-party source code, and we have to write a Func function that belongs to us according to this function. Are we at a glance when we're done rewriting it? For example, before rewriting, throw a 11 exception, the corresponding will print out-3, we have to find out what this-3 means. Let's comment out the Demo function and see the following compilation results

The output is at a glance and you see the timeout exception directly. Then we will directly locate the problem, so that efficiency will be improved. In C + +, the type of the exception can be a custom class type, the match for class-type exceptions is still the top-down strict match, and the assignment compatibility principle still applies in exception matching. In general, the catch that matches the subclass exception is placed at the top, and the catch that matches the parent exception is placed in the lower part. A series of exception classes are defined in the project, and each class represents an exception type that may occur in the project . Code reuse may require explaining different exception classes, and it is recommended to use references as parameters when defining a catch statement.

Next, we'll take the code as an example to analyze

#include  <iostream> #include  <string>using namespace std;class Base{}; class exception : public base{    int m_id;     string m_desc;public:    exception (INT&NBSP;ID,&NBSP;STRING&NBSP;DESC)      {        m_id = id;         m_desc = desc;    }         int id ()  const    {         return m_id;    }        string  Description ()  const    {        return m _desc;    }};/*     assumes:  functions in the current functional third-party library, so we cannot modify the source code         &nbSP; function name:  void func (int i)      type of exception thrown: int                          -1 ==>  parameter Exceptions                          -2 ==>  Run Exceptions                           -3 ==>  Timeout Exception */void func (int i) {    if ( i  < 0 )     {        throw -1 ;     }        if ( i > 100 )     {        throw -2;     }   &nbSp;    if ( i == 11 )     {         throw -3;    }         cout <<  "Run func ..." &NBSP;&LT;&LT;&NBSP;ENDL;} Void myfunc (int i) {    try    {         func (i);     }    catch (int i)      {        switch (i)          {            case -1:                 throw exception (-1,   "Invalid parameter");                 break;            case -2:                 throw exception ( -2,  "runtime exception");                 break;             case -3:                 throw exception ( -3,  "Timeout Exception");                 break;         }    }}int main () {    try     {        myfunc (one);     }     catch (const exception& e)     {         cout <<  "exception info: "  << endl;         cout <<  "    ID: "  << e.id ()   << endl;        cout <<  "     Description:  " << e.description ()  << endl;    }     catch (const base& e)     {         cout <<  catch (const base& e)  << endl;     }    return 0;}

We see that we have defined two classes, defined IDs and description to describe them in class Exception, and then generated temporary objects in the MyFunc function Exception to get their information, let's look at the results of the compilation

This information is not more intuitive. If we put the parent class in the above catch statement in front of the subclass, look at the result

We see that the compilation has been warned, and it prints the information of the parent class after it is run, because it also follows the assignment compatibility principle. As we said before, the catch matching the subclass exception is placed in the upper part, and the catch matching the parent exception is placed in the lower part. Be sure to follow this rule. The exception class family is provided in the C + + standard library, the exceptions in the standard library are derived from the exception class, and the exception class has two main branches:a> logic_error is often used in programs to avoid logic errors;b> runtime_ Error is often used for malignant errors that cannot be avoided in a program . Is the exception class relationship in the standard library

Through the study of the anomaly, summarized as follows:1, C + + directly support the concept of exception handling; 2, Try...catch. is specialized in C + + exception processing, 3, the try statement handles the normal code logic, the catch statement handles the exception condition, the same try statement can keep up with multiple catch statements, 4, the exception processing must match strictly, do not make any conversion; 5, the catch statement block can throw an exception, The type of the exception can be a custom class type, 6, the assignment compatibility principle is still applicable in the exception match; 7. Exceptions in the standard library are derived from the exception class.


Welcome Everybody to learn C + + language together, can add me qq:243343083.

Exception handling in C + + (53)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.