That is what catching exception is all about. If you know how to handle the problem you catch the exception so that the program can continue from there. If you don't know how to handle the problem it's better to just let the exception get thrown further up the call stack, where it might be possible to handle it.
it's better to just let the exception get thrown further up the call stack, where it might be possible to handle it.
Which is on the main() level rather unlikely.
Why do you throw and catch at the same time? A simple if would the job.
Apart from that I'd guess that you want a single try block and two(?) catch blocks that handles InvalidDay and InvalidMonth (why doesn't something like InvalidYear exists?)
InvalidYear it is optional for my teacher. But if i give two catch blocks, won't the first one to catch error will only execute even if invalid day and invalid months?
But if i give two catch blocks, won't the first one to catch error will only execute even if invalid day and invalid months?
The InvalidDay& catch blocks will only catch InvalidDay exceptions and the InvalidMonth& one just InvalidMonth exceptions.
You could derive your custom exceptions from std::runtime_error (which is actually good practice.) If you do so you could then use a single std::exception& catch block instead. http://www.cplusplus.com/reference/stdexcept/runtime_error/
Note that the order of the catch blocks does matter if you are catching the base class of an exception as well. If I reorder test() so std::exception is caught first
void test(int testCase) {
try {
switch(testCase) {
case 1: throw FooError(); break;
case 2: throw BarError(); break;
case 3: throw bad_alloc(); break; // standard exception for out of memory conditions
default: throw UnknownError();
}
}
catch(const exception& e) {
cerr << "caught exception : " << e.what() << "\n";
}
catch(const FooError& e) {
cerr << "caught FooError : " << e.what() << "\n";
}
catch(const BarError& e) {
cerr << "caught BarError : " << e.what() << "\n";
}
catch(...) {
// "catch all" -- must be last!
// As we have no idea what we're caught, and therefore no idea what the state
// of the program is, then we need to abort (ideally after saving any data to file.)
cerr << "caught unknown exception - aborting!\n";
exit(0);
}
}
That is, all except the unknown exception are handled byt the std::exception catch block.
(GCC did warn me that I was wasting my time with the FooError and BarError catch block as I had the compiler warning level high enough.)
Andy
PS I don't quite see the need for the conditions in your InvalidMonth and InvalidDay constructors (the exceptions are only raised if the month or day is already know to be invalid, using the tests starting on lines 114 (for month) and 126 (for day), yes?)