Professional C__ - Marc Gregoire [163]
void myUnexpected()
{
cerr << "Unexpected exception!" << endl;
throw runtime_error("");
}
Code snippet from ReadIntegerFile\UnexpectedExceptions.cpp
This code converts an unexpected exception to a runtime_error exception, which the function readIntegerFile() has in its throw list.
You could set this unexpected exception handler in main() with the set_unexpected() function. Like set_terminate(), set_unexpected() returns the current handler. The unexpected() function applies program-wide, not just to this function, so you should reset the handler when you are done with the code that needed your special handler:
int main()
{
vector const string fileName = "IntegerFile.txt"; unexpected_handler old_handler = set_unexpected(myUnexpected); try { readIntegerFile(fileName, myInts); } catch (const invalid_argument& e) { cerr << "Unable to open file " << fileName << endl; return 1; } catch (const runtime_error& e) { cerr << "Error reading file " << fileName << endl; return 1; } catch (int x) { cerr << "Caught int" << endl; } set_unexpected(old_handler); // Remainder of function omitted } Code snippet from ReadIntegerFile\UnexpectedExceptions.cpp Now main() handles any exception thrown from readIntegerFile() by converting it to a runtime_error. However, as with set_terminate(), we recommend using this capability judiciously. unexpected(), set_unexpected(), and bad_exception are all declared in the Changing the Throw List in Overridden Methods When you override a virtual method in a subclass, you can change the throw list as long as you make it more restrictive than the throw list in the superclass. The following changes qualify as more restrictive: Removing exceptions from the list Adding subclasses of exceptions that appear in the superclass throw list Making it a noexcept method The following changes do not qualify as more restrictive: Adding exceptions to the list that are not subclasses of exceptions in the superclass throw list Removing the throw list entirely If you change throw lists when you override methods, remember that any code that called the superclass version of the method must be able to call the subclass version. Thus, you can’t add exceptions. For example, suppose that you have the following superclass: class Base { public: virtual void func() throw(exception) { cout << "Base!\n"; } }; Code snippet from ThrowListsVirtualMethods\CorrectOne.cpp You could write a subclass that overrides func() and specifies that it doesn’t throw any exceptions: class Derived : public Base { public: virtual void func() noexcept { cout << "Derived!\n"; } }; Code snippet from ThrowListsVirtualMethods\CorrectOne.cpp You could also override func() such that it throws a runtime_error as well as an exception, because runtime_error is a subclass of exception. class Derived : public Base { public: virtual void func() throw(exception, runtime_error) { cout << "Derived!\n"; } }; Code snippet from