An example of custom C++ exception handling is illustrated

  • 2020-05-30 20:55:29
  • OfStack

Examples illustrate custom C++ exception handling

Example 1: customize an exception class myException inherited from excepton

C++ standard, defined in < stdexcept > Any exception class in exception is derived from exception Class, and this example is simply inherited by exception, throwing an exception in try and catching it. The code is as follows:


/*++ test.cpp 
version:1.0 
decript:define a exception class named myException 
    derived from base class exception 
    which is declared in <exception> 
created:2011-08-14 
author: btwsmile 
--*/ 
#include<exception> 
#include<iostream> 
using namespace std; 
 
//customized exception class 'myException' 
class myException:public exception 
{ 
public: 
  myException():exception("ERROR! Don't divide a number by integer zero.\n") 
  { 
  } 
}; 
//entry of the application 
int main() 
{ 
  int x=100,y=0; 
  try 
  { 
    if(y==0) throw myException(); 
    else cout<<x/y; 
  } 
  catch(myException& me) 
  { 
    cout<<me.what(); 
  } 
  system("pause"); 
  return 0; 
} 

The results are as follows:


ERROR! Don't divide a number by integer zero.

Please press any key to continue..

Apparently, the exception was caught. It should be noted here that VC extends the exception handling class exception, and this example USES exception("ERROR! ..." For this reason, the C++ standard does not allow it.

At the same time, VC is not standards-compliant and strongly supports terminate and unexpected. It only preserves the syntax, but does not support it at compile time. To better understand the exception handling of C++ by combining terminate and unexpected, the following example is implemented using Dev cpp IDE.

Example 2: implement the custom exception class myException in accordance with the C++ standard and encapsulate the throw statement into the function check(). The changes involved are as described in the title. (2) encapsulate throw myException() into check() function; (3) allow the check() function to throw an exception of type myException. The code is as follows:


/*++ test.cpp 
version:1.1 
decript:define a exception class named myException 
    according to C++ standard, 
    derived from base class exception 
    which is declared in <exception> 
    !also,encapusulate throw into a function 
created:2011-08-14 
author: btwsmile 
--*/ 
#include<exception> 
#include<iostream> 
using namespace std; 
 
//customized exception class 'myException' 
class myException:public exception 
{ 
public: 
  const char* what()const throw()//#1  
  { 
    return "ERROR! Don't divide a number by integer zero.\n"; 
  }   
}; 
void check(int y) throw(myException)//#2 
{ 
   if(y==0) throw myException(); 
} 
//entry of the application 
int main() 
{ 
  int x=100,y=0; 
  try 
  { 
    check(y); 
    cout<<x/y; 
  } 
  catch(myException& me) 
  { 
    cout<<me.what(); 
  } 
  system("pause"); 
  return 0; 
} 

The result is exactly the same as in example 1. Note that the throw list, immediately following check(), indicates the types of exceptions that the function is allowed to throw. The question has to be raised here, what happens if an exception type is thrown that is not allowed?

Example 3: throws an unexpected exception

The throw list, which follows the check body, specifies the type of exception allowed to be thrown, and 1 violation triggers unexpected. You can think of unexpected as an CALLBACK function that the system calls automatically, but you can also manually trigger its execution. This case falls into the former category. The code is as follows:


 
/*++ test.cpp 
version:1.3 
decript:define an unexpected excption handler, 
    set it by using set_unexpected, 
    modify the throw list of function check 
created:2011-08-14 
author: btwsmile 
--*/ 
#include<exception> 
#include<iostream> 
using namespace std; 
 
//customized exception class 'myException' 
class myException:public exception 
{ 
public: 
  const char* what()const throw() 
  { 
    return "ERROR! Don't divide a number by integer zero.\n"; 
  }   
}; 
void check(int y) throw()//#1 only int-type exception is permitted 
{ 
   if(y==0) throw myException(); 
} 
void myUnexpected() 
{ 
   cout<<"Unexpected exception caught!\n"; 
   system("pause"); 
   exit(-1); 
} 
//entry of the application 
int main() 
{ 
  unexpected_handler oldHandler=set_unexpected(myUnexpected); 
  int x=100,y=0; 
  try 
  { 
    check(y); 
    cout<<x/y; 
  } 
  catch(myException& me) 
  { 
    cout<<me.what(); 
  } 
  system("pause"); 
  return 0; 
} 

The results are as follows:


Unexpected exception caught!

Please press any key to continue..

The throw list of the check function is empty, meaning that no exception of any kind is allowed to be thrown, but in practice, when an exception occurs, the system cannot ignore it and calls the unexpected handler. Therefore, restricting the list of one function throw to be empty is a cautionfor programmers and requires special attention. You can get the same result if you change the code at #1 to throw(int) and so on. An unexpected exception is simply an exception that the body of the function allows to be thrown outside the scope of the exception type. If there is no throw at all after the check function, any type of exception to the function is allowed.

Example 4: throw an exception allowed by the body of a function, but not caught

Consider this question: what happens if the check function throw has an exception type myException in its throw list, and it does throw an exception of myException at y==0, but it is not received by catch?

Before formally answering this question, discuss what it means to be "not present by catch". For example, the code for example 3 would look like this :(## is where the changes were made)


/*++ test.cpp 
version:1.4.1 
decript: 
    how to understand "exception not caucht"? 
created:2011-08-14 
author: btwsmile 
--*/ 
#include<exception> 
#include<iostream> 
using namespace std; 
 
//customized exception class 'myException' 
class myException:public exception 
{ 
public: 
  const char* what()const throw() 
  { 
    return "ERROR! Don't divide a number by integer zero.\n"; 
  }   
}; 
void check(int y) //any type of exception is permitted 
{ 
   if(y==0) throw myException(); 
} 
void myUnexpected() 
{ 
   cout<<"Unexpected exception caught!\n"; 
   system("pause"); 
   exit(-1); 
} 
//entry of the application 
int main() 
{ 
  unexpected_handler oldHandler=set_unexpected(myUnexpected); 
  int x=100,y=0; 
  try 
  { 
    check(y); 
    cout<<x/y; 
  } 
  catch(int &e) //##1 no catch sentence matches the throw type 
  { 
    cout<<e<<endl; 
  } 
  /*        ##2 if add this part, any type which's not handler before will 
            be caught 
  catch(...) 
  { 
          cout<<"Unkown exception caught!\n"; 
     } 
  */ 
  system("pause"); 
  return 0; 
} 

Compile and run, the program will fail because the myException exception thrown by the check function is not handled. By default, when an exception is thrown and not handled, the system will automatically call the abort() function, which is allowed to terminate the program, and you will see this prompt in the console:


This application has requested the Runtime to terminate it in an unusual way.Please contact the 
application's support team for more information.

However, you can add part ##2, catch(...) Means to catch any type of exception.

Note: exception types that are not allowed by the check function do not enter into the judgment of the catch statement, so catch(...) It has no effect on unexpected exception.
Still consider the case without the ##2 part. As mentioned earlier, the system will automatically call the abort() function to terminate the program. In fact, it triggers terminate, which is similar to unexpected, and you can still customize the terminate process. Even terminate is similar to unexpected in grammar. The modified code is:


/*++ test.cpp 
version:1.4.2 
decript: 
    how to understand "exception not caucht"? 
created:2011-08-14 
author: btwsmile 
--*/ 
#include<exception> 
#include<iostream> 
using namespace std; 
 
//customized exception class 'myException' 
class myException:public exception 
{ 
public: 
  const char* what()const throw() 
  { 
    return "ERROR! Don't divide a number by integer zero.\n"; 
  }   
}; 
void check(int y) //any type of exception is permitted 
{ 
   if(y==0) throw myException(); 
} 
void myUnexpected() 
{ 
   cout<<"Unexpected exception caught!\n"; 
   system("pause"); 
   exit(-1); 
} 
void myTerminate() //##1 set it be the terminate handler 
{ 
   cout<<"Unhandler exception!\n"; 
   system("pause"); 
   exit(-1); 
} 
//entry of the application 
int main() 
{ 
  unexpected_handler oldHandler=set_unexpected(myUnexpected); 
  terminate_handler preHandler=set_terminate(myTerminate); 
  int x=100,y=0; 
  try 
  { 
    check(y); 
    cout<<x/y; 
  } 
  catch(int &e) //no catch sentence matches the throw type 
  { 
    cout<<e<<endl; 
  } 
  system("pause"); 
  return 0; 
} 

The results are as follows:


Unhandler exception!

Please press any key to continue..

Conclusion: C++ provides friendly support for exception handling.

Users can customize the exception type, and the exception type is not restricted. It can be a built-in data type such as int,double, etc., or it can be a custom class, or it can be inherited from C++ an exception class. Example 1 USES a method derived from exception.

In addition, when defining a function, you can explicitly specify the type of exception thrown by the function body. Implicitly, the default allows a function to throw any type of exception. You can add an throw statement to restrict the type of exception. In particular, throw() means that functions are not allowed to throw any type of exception. If the exception type specified in the throw list is violated, the system will call unexpected hanlder for handling, and you can customize the unexpected exception handling method. They are illustrated in examples 2 and 3.

If a valid exception to the throw list of function bodies is thrown, but not caught by the program, the system calls terminate handler for processing. By default, you simply call the abort() function to terminate the program, and you can also customize the terminate handling method. It is illustrated in example 4.

If you have any questions, please leave a message or come to the site community to exchange discussion, thank you for reading, hope to help you, thank you for your support of the site!


Related articles: