Exceptions
Contents
Custom Exception
We can also throw an object of our own class.File: except6.cpp
#include <iostream> #include <fstream> using namespace std; class MyException { public: string messg ; MyException( string str1 ) { messg = str1 ; } }; int main() { try { throw MyException("Error") ; } catch ( MyException& e1 ) { cout << e1.messg << endl ; } return 0; } $ g++ except6.cpp ; ./a.exe Error Notice we have been using the reference in the catch statement catch ( MyException& e1 ) The below program shows the difference between using regular objects instead of references.
File: scope1.cpp
#include <iostream> #include <fstream> using namespace std; class MyException { public: string messg ; MyException( string str1 ) { messg = str1 ; cout << "MyException: constructor: " << messg << endl ; } MyException( const MyException& obj1 ) { messg = obj1.messg ; cout << "MyException: copy constructor: " << messg << endl ; } ~MyException( ) { cout << "MyException: destructor: " << messg << endl ; } }; int main() { try { MyException error1("Error 1:") ; throw MyException("Error 2:") ; } catch ( MyException error2 ) { cout << error2.messg << endl ; } cout << "Step 1:" << endl ; try { throw MyException("Error 3:") ; } catch( MyException& error3 ) { cout << error3.messg << endl ; } cout << "Step 2:" << endl ; return 0; } $ g++ scope1.cpp ; ./a.exe MyException: constructor: Error 1: MyException: constructor: Error 2: MyException: destructor: Error 1: MyException: copy constructor: Error 2: Error 2: MyException: destructor: Error 2: MyException: destructor: Error 2: Step 1: MyException: constructor: Error 3: Error 3: MyException: destructor: Error 3: Step 2: The lines get executed first. try { MyException error1("Error 1:") ; throw MyException("Error 2:") ; } catch ( MyException error2 ) { cout << error2.messg << endl ; } MyException error1("Error 1:") ; This creates the "error1" object and the statement: MyException: constructor: Error 1: Then we hit the "throw" statement: throw MyException("Error 2:") ; This will create an object and we get the below statement printed out: MyException: constructor: Error 2: We come to the handler but before doing that we need to clean up the local objects in the "try" block and the destructor for "error1" object get called. catch ( MyException error2 ) { cout << error2.messg << endl ; } The object with the message "Error 2" from the try block is copied to "error2" object. MyException: copy constructor: Error 2: We print out the message "Error 2:" and the come out of the handler. This causes the cleanup of the 2 "Error 2" objects: one that was thrown and the other one that was in the argument to the catch handler. We print out a debug statement and then hit the lines: try { throw MyException("Error 3:") ; } catch( MyException& error3 ) { cout << error3.messg << endl ; } Step 1: MyException: constructor: Error 3: Error 3: MyException: destructor: Error 3: Step 2: We create the "Error 3:" object in the "try" block and then jump to the handler. Since the argument "error3" is a reference we do not create another object and only 1 constructor is called as shown in the output.