Question
C++ Sometimes you may want to delay handling an exception. For example, you may have a function with code that throws an exception if there
C++
Sometimes you may want to delay handling an exception.
For example, you may have a function with code that throws an exception if there is an attempt to divide by zero, but you may not want to catch the exception in that function. This becomes an important issue because one program that uses this function should end if the exception is thrown, and other programs that use this function may want to do something else. So in such cases, it makes sense to not catch the exception in the function definition, but instead to have any program that uses the function place the function invocation in a try-block and then catch the exception in a catch-block that follows that try-block.
//This program illustrates throwing an exception inside a function #include
class DivideByZero {};
double safe_divide(int top, int bottom) throw (DivideByZero);
int main() { int numerator; int denominator; double quotient; cout << "Enter numerator: "; cin >> numerator; cout << "Enter denominator: "; cin >> denominator;
try { quotient = safe_divide(numerator, denominator); } catch(DivideByZero) { cout << "Error: Division by zero! " << "Program aborting. "; exit(0); }
cout << numerator << "/" << denominator << " = " << quotient << endl;
cout << "End of program. "; return 0; }
double safe_divide(int top, int bottom) throw (DivideByZero) { if (bottom == 0) throw DivideByZero();
return top/double(bottom); }
In this program there is no throw statement visible in the try-block. The statement that does the throwing in that program is:
if (bottom == 0) throw DivideByZero();
and it is not visible in the try-block, however, it is in the try-block in terms of program execution. If you look closely, you will see an if statement in the body of function safe_divide which will be invoked in the try-block.
Exception Specifications If a function does not catch an exception, it should at least warn programmers that any invocation of the function might possibly throw an exception. If there are exceptions that might be thrown, but not caught in the function definition, then those exception types should be listed in an exception specification, which is illustrated by the following:
double safe_divide(int top, int bottom) throw (DivideByZero);
The exception specification must appear in both the function declaration and the function definition. If a function has more than one declaration, all function declarations must have the same exception specification. The exception specification is also referred to as a throw-list.
If more than one exception is thrown in a function, then they are separated by commas:
void some_function( ) throw (DivideByZero, OtherException);
If an exception is thrown into a function but that function does not include the specification, then the program ends once it has reached the exception situation.
Experiment 1 The following program solves a quadratic equation. Use the concepts that you have learned in this activity to rewrite the program such that it uses the exception handlers to handle exceptional situations.
// Program to solve quadratic equation #include
using namespace std; void all_zero( ); void roots(double a, double b, double c);
int main( ) { double a, b, c; // coefficient of ax^2 + bx + c = 0 cout << "Enter the three coefficients "; cin >> a >> b >> c;
roots(a, b, c);
return 0; }
void all_zero( ) { exit(1); }
void roots(double a, double b, double c) { double x1, x2; // The two roots double temp;
if( !(a == 0 && b == 0 && c == 0) ) { if(a != 0) { temp = b*b - 4*a*c; if(temp >= 0) { // Two roots x1 = ( -b + sqrt(temp))/2*a; x2 = ( -b - sqrt(temp))/2*a; cout << "The two roots are: " << x1 << " and " << x2 << endl; } else { cout << "Square root of negative values is not defined "; exit(1); }
} else { cout << "Division by zero, not defined "; exit(1); } } else { all_zero( ); } }
So we talked about exception handling and went through some examples, but we never discussed how to make a good and realistic use of exception handling.
When to Throw an Exception
In complicated programs you may want to separate throwing an exception and catching the exception into separate functions. In most cases, you should include any throw-statement within a function definition, list the exception in the exception specification for that function, and place the catch-clause in a different function. Here is a preferred way to do this:
void functionA( ) throw (MyException) { ... ... throw MyException(
Then in some other function we will have:
void functionB( ) { ... try { ... ... functionA( ); ... ... } catch(MyException e) {
In general, you want to use throw-statements within functions listed in an exception specification for the function.
Experiment 2:
We will examine an object-oriented approach to exception handling. Recall the Rectangle class discussed before. Write an improved version of the Rectangle class, or define a Triangle class.
The version throws multiple exceptions. (rectangle.h and rectangle.cpp)
Sample Output:
Enter the rectangle's width: -1
Enter the rectangle's length: 10
Error: A negative value was given for the rectangle's width.
End of the program.
Press any key to continue . . .
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started