"C + +" Analysis of anomalies

Source: Internet
Author: User
Tags throw exception

The so-called anomaly, as the name implies is not normal, there are problems.

For people who have abnormal time is sick body discomfort, then for the program is the same, there is abnormal code is "sick."

Then, since the illness is to be treated, the remedy is necessary! This will return to normal.


The abolition of so many words, or lead to our C + + "exception" concept.

exception , so that a function can throw an exception when it finds an error that it cannot handle, and that the caller can handle the problem directly or indirectly.

and the traditional exception handling method:

1. Termination procedures

2. Returns a value that represents an error (many system functions, such as malloc, insufficient memory, allocation failure, return null pointer)

3. Return a legal value that keeps the program in some sort of illegal state (most pit-daddy stuff, some third-party libraries really do)

4. Invoke a function that is ready to be used in case of "error".


The first case is not allowed, the unconditional termination of the application of the library can not be used in the machine can not be in the program.

The second case, more commonly used, but sometimes inappropriate, such as the return error code is int, each call to check the error value, very inconvenient, but also easy to double the program size (but to precisely control the logic, I think this is a good way).

In the third case, it is easy to mislead the caller, in case the caller does not check the global variable errno or otherwise checks the error, it is a disaster, and this method does not work well in concurrent situations.

As for the fourth situation, I feel less use, and the callback code should not appear more.



Using exceptions, the error and processing are separated, the library function throws an exception, the caller catches the exception, the caller can know that the Program function library call error, and to deal with, and whether to terminate the program is in the caller's hand.

However, error handling is still a difficult task, and C + + 's exception mechanism provides programmers with a way to handle errors, allowing programmers to handle errors in a more natural way.


Suppose we write a program that simply divides the program:

int Div (int a, int b) {if (b = = 0) exit (1);//if return 0; (not advisable, return 1 is 10/100) return a/b;}    int main () {int a = 10;  int b = 2;    What if B = 0?    Cout<<div (b) <<endl; return 0;}

Such a program, at first glance is really no problem, but the program in the execution when the divisor is 0 o'clock terminated, the termination means that the program will not continue to execute, this is the so-called exception. But is it a bit simple and rude to just stop?? This is generally not the result we want.

Three axes in C + + exceptions:try,throw,catch

①. Test if a program will not be abnormal

②. If an exception occurs, the exception is thrown by throw (note: The type of the variable is thrown)

③. Capturing the appropriate exception, that is, matching the type of exception, for targeted processing


Corresponding Code:

float div (int a, int b) {    if (b  == 0)     {       throw b;//Throw exception            }    return a/b;} Int main () {    int a = 10;    int b =  0;    float result = 0.0f;    try     {       result = div (A, b);     }      catch (int)     {         cout<< "div error!, divisor is 0" <<endl;    }    cout< < "result = " <<div (A, b) <<endl;        return  0;} 

Run the result:

650) this.width=650; "src=" Http://s2.51cto.com/wyfs02/M00/7D/C4/wKiom1bvhbXwWdGYAAAL20W8e10811.png "title=" capture. PNG "alt=" Wkiom1bvhbxwwdgyaaal20w8e10811.png "/>

We found that the program crashed (except for the forced End program) without throwing an exception, and now it does not crash and reflects the problem.

In fact, the program contains anomalies in its own processing, will be handed over to the operating system to handle, and the operating system management of the entire machine normal operation, encountered this anomaly, it will directly fits, end the program, so there will be a crash. If the program itself writes exception handling, the exception is handled by itself. In other words, the exception handling mechanism is the operating system issued by the two-level institutions, the two-level institutions specifically for their own programs set the exception to deal with.


And, the program is not a return value, we look at the following:

650) this.width=650; "src=" Http://s1.51cto.com/wyfs02/M02/7D/C4/wKiom1bvi--y_jdoAAAgXWj4HGk286.png "title=" 23.PNG "alt=" Wkiom1bvi--y_jdoaaagxwj4hgk286.png "/>


Normal return to the left, an exception occurs from the right to return, after an exception, the code after the throw will no longer execute, directly find catch awakened capture. Then by the exception specification :

Class Test{};float Div (int a, int b) throw (int,double,short,test)

This means that the function can only throw the base type Int,double,short, and the custom type test

float Div (int a, int b) throw ()

This means that the function cannot throw an exception

float Div (int a, int b)

This delegate may throw any exception


There is another type-matching problem at the time of capture:

Float div (int a, int b) {    if (b == 0)      {        short x = 0;         throw x;//Throw Exception           }     return a/b;} Int main () {    int a = 10;    int b =  0;    float result = 0.0f;    try     {       result = div (A, b);     }      catch (int)     {         cout<< "div error! (int) with a divisor of 0 "<<endl;    }    catch (short)     {         cout<< "Div error! (short), divisor is 0 "<<endl;    }        // What if I throw a double or char or something? Do you want to keep adding catch?    //? Other types can be captured in the following ways          catch (...)  //  captures the above int and short, and can only be placed at the end!     {        cout<< "div error! ( All), divisor is 0 "<<endl;    }    cout<<" result =  "< <div (A, b) <<endl;        return 0;}

Does this have a lot like oh we learned before switch (); Case: What about the statement?

Switch () {case:case:.    . Default:}

It is equivalent to saying that you cannot match all case statements and then execute default. Also, this is true in exceptions.

Summarize:

Throwing and capturing of exceptions

    1. An exception is thrown by throwing an object, and the type of the object determines which processing code should be activated.

    2. The processing code that is selected is the one that matches the object type in the call chain and is closest to the exception where it was thrown.

    3. When an exception is thrown, the local storage object is freed, so the thrown object is returned to the system, and the throw expression initializes a special copy of the exception object (the anonymous object), the exception object is compiled and managed, and the exception object is revoked after it is passed to the corresponding catch handler.


      Stack expansion

1. When an exception is thrown, the execution of the current function is paused, and the corresponding matching catch clause is started to be found.

2. First check if the throw itself is inside the catch block, and if it is looking for a matching catch statement.

3. If there is a match, then the processing. Does not exit the current function stack and continues to look in the stack of the calling function.

4. Repeat the above process. if the stack of the main function is reached, there is still no match, then the program terminates.

5. The process of finding a matching catch clause along the call chain is called a stack unwind .

After a matching catch clause is found and processed, it continues to execute after the catch clause.


Above, we understand the principle of exception handling mechanism.

For large program code, you need to handle exceptions for custom types.

The following are the custom type matches:

#include  <iostream> #include  <string>using namespace std;class exception{ Public :     exception (INT&NBSP;ERRID,&NBSP;CONST&NBSP;CHAR&NBSP;*&NBSP;ERRMSG)          : _errid (errid )           , _errmsg (errmsg )     {}      void what  ()  const    {           cout<< "Errid:"  <<_errId<< endl;           cout<< "ErrMsg:" &NBSP;&LT;&LT;_ERRMSG&LT;&LT;&NBSP;ENDL;&NBSP;&NBSP;&NBSP;&NBSP;} private :     int _errid ;       //   Error Codes      string _errMsg ;  //  error messages};void func1   (Bool isthrow){     // ...     if  (isThrow )      {          throw Exception  (1,  " Throw  excepton Object " );    }     // ...      printf ("Func1 (%d) \ n"  , isthrow); void func2  (bool isthrowstring, bool isthrowint) {     //  ...     if  (isthrowstring )     {           throw string  ("Throw  string object"  );     }     // ...     if (isThrowInt )      {          throw 7;     }     printf ("Func2 (%d, %d) \ n"  , isthrowstring, isthrowint );} void func  () {     try    {     &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;FUNC1 (false );          &NBSP;FUNC2 (true , true);     }     catch (const  STRING&AMP;&NBSP;ERRMSG)     {           cout<< "Catch string object:" &NBSP;&LT;&LT;ERRMSG&LT;&LT;&NBSP;ENDL;&NBSP;&NBSP;&NBSP;&NBSP;}      catch (Int errid)     {           cout<< "Catch int object:"  <<errId<< endl;     }     catch (const exception& e)      {          e.What  ();    }     catch (...)     {          cout<< "  Unknown exception" << endl;    }      printf  ("Func () \ n");} Int main () {    func ();     return 0;}

Exception re-throw

It is possible that a single catch cannot handle an exception completely, and after some correction is made, it is hoped that the outer call chain function will be processed, and the catch can be handled by re-throwing the exception to the higher-level function.

Class exception{public :     exception (int errid = 0,  const char * errmsg =  ""  )           :  _errid (errid )          , _errmsg (errMsg )     {}     void What  ()  const     {          cout<< "Errid:"  <<_errid << endl;          cout<< "ErrMsg:"  < <_errmsg<< endl;    }private :     int _ errid ;       //  Error code      string _ errmsg ;  //  error Message};void func1  () {     throw string   ("Throw funC1 string ");} void func2  () {     try    {           func1 ();     }     catch ( STRING&NBSP;&AMP;&NBSP;ERRMSG)     {           cout<<errmsg <<endl;          // exception e  (1,  "rethorw exception");           //throw e ;          // throw;           // throw errMsg;     }}void func3  () {     try    {     &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;FUNC2 ();    }     catch  (exception &Amp; e)     {          e.What  ( );     }}

exceptions and Constructors & destructors

    1. constructor to complete the construction and initialization of the object, you need to ensure that you do not throw an exception in the constructor, otherwise it may result in incomplete or incomplete initialization of the object.

    2. The destructor mainly completes the cleanup of resources and needs to ensure that no exceptions are thrown within the destructor, which could lead to resource leaks (memory leaks, handles not closed, etc.)


The exception class is a standard exception class defined by C + +, and we typically define an appropriate exception class by inheriting the exception class.

http://www.cplusplus.com/reference/exception/exception/

This article is simply from the exception of the use of the scene, introduced the basic use of methods, some advanced exception usage is not listed, but also to be supplemented, biased text may be flawed, I hope you point out



This article from "vs LV" blog, reproduced please contact the author!

"C + +" Analysis of anomalies

Related Article

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.