Classes and Exception Handling In C++ - c++

I've run across a coding problem that I'm having trouble understanding (note the line tagged with //-):
#include <iostream>
using namespace std;
class X { };
class X0 { };
class X1: public X0 { };
class X2: public X1 { };
void f(int i) {
if (i == 0) {
throw X0();
} else if (i == 1) {
throw X1();
} else if (i == 2) {
throw X2();
} else {
throw X();
}
}
int main(int argc, char* argv[]) {
try {
f(0); //-
} catch (X1) {
cout << "A" << endl;
} catch (X2) {
cout << "B" << endl;
} catch (X0) {
cout << "C" << endl;
} catch (...) {
cout << "D" << endl;
}
}
The output of this code is C, as expected. If I change the tagged line to "f(1);" the output is A, also as expected.
However, if I change the tagged line to "f(2);" the answer is also A, and I'm not understanding why. I feel like it may have something to do with the scope of the destructors, but my attempts to find information on it haven't been successful because I'm not entirely sure what to study. Would anyone be able to explain what is happening here, or just the name of concept this problem is illustrating so I can research it? Any help is appreciated.

An X2 inherits from X1 and so "is" an X1, and the catch block for X1 is first so triggers before we reach the X2 one.

When i == 2 , you throw an X2, X2 is derived from X1.
The order of catches matter, you attempt to catch X1 first, X2 (what you threw) is an X1, so that is the catch that fires. You need to reorder your catches to catch the most specific first

However, if I change the tagged line to "f(2);" the answer is also A, and I'm not understanding why.
This is because X2 is subclass of X1.
When you call f(2) in try, f(2) throws X2. It seems like the exception should be caught in catch(X2). However, X2 is subclass of X1.
So the exception is caught in catch(X1) and the code inside catch prints A.
So if you want to see B when you call f(2), the code should be like this.
//skipped some code
int main(int argc, char* argv[]) {
try {
f(2); //-
} catch (X2) {
cout << "B" << endl;
} catch (X1) {
cout << "A" << endl;
} catch (X0) {
cout << "C" << endl;
} catch (...) {
cout << "D" << endl;
}
}

You should catch X2 before X1, as it is derived from X1, otherwise the catch for X1 catches X2 as well.
In Java this would have been a compilation error.

The type of exception is matched in the order of catch clauses under the matching rules (http://en.cppreference.com/w/cpp/language/try_catch):
T is an unambiguous public base class of E
X1 is public base class of X2 so it's a match.

Related

How can I simplify this program? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I'm writing a program that finds the roots of a quadratic equation using exception handling and i'm wondering if there's a way I can simplify the program, I have a bunch of empty classes for the catch cases
// Program to solve quadratic equation
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;
class all_zero{
};
class negative{
};
class zero_division{
};
void roots(double a, double b, double c) throw (all_zero,negative,zero_division);
int main(){
double a, b, c; // coefficient of ax“2 + bx + c= 0
cout << "Enter the three coefficients \n";
cin >> a >> b >> c;
try
{
roots(a, b, c);
}
catch(all_zero) {cout << "All values are zero \n";}
catch(negative) {cout << "Square root of negative values is not defined \n";}
catch(zero_division) {cout << "Division by zero, not defined \n";}
return 0;
}
void roots(double a, double b, double c) throw (all_zero,negative,zero_division){
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){
x1 =(-b + sqrt(temp))/2*a;
x2 = (-b - sqrt(temp))/2*a;
cout << "The two roots are: "<< x1 <<" and " << x2 << endl;
}else{throw negative();}
}else{throw zero_division();}
}else{throw all_zero();}
}
Is there a way I can make it so i dont have just empty classes or a way to put them into maybe a struct?
Note that the dynamic excpetion specification you are using is deprecated in C++11 and removed in C++17:
void roots(double a, double b, double c) throw (all_zero,negative,zero_division)
// ^^
You can just remove it.
using namespace std; is considered bad practice.
Do not use std::endl to add a newline. std::endl adds a new line and flushes the stream. Most of the time this is unnecessary. Use '\n' to add a newline.
Is there a way I can make it so i dont have just empty classes or a way to put them into maybe a struct?
Actually, I don't see the bad about having seperate classes for the different types of exceptions. The downside of your approach is that the "what" is in the catch, not part of the exception or coming from where the exception occured. I'll show you the first (message is part of the type) and hope you will see how to realize the latter (message is from where the exception is thrown).
You can inherit from std::runtime_error which offers a what() method that returns a string passed to the constructor. This also makes it easier for others to catch your exceptions, because std::runtime_error in turn inherits from std::excpetion which is the base class of all standard exceptions:
// Program to solve quadratic equation
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <stdexcept>
struct all_zero : std::runtime_error {
all_zero() : std::runtime_error("All values are zero") {}
};
struct negative : std::runtime_error {
negative() : std::runtime_error("Square root of negative values is not defined") {}
};
struct zero_division : std::runtime_error {
zero_division() : std::runtime_error("Division by zero, not defined") {}
};
void roots(double a, double b, double c);
int main(){
double a, b, c; // coefficient of ax“2 + bx + c= 0
std::cout << "Enter the three coefficients \n";
std::cin >> a >> b >> c;
try
{
roots(a, b, c);
}
catch(std::runtime_error& ex) {std::cout << ex.what() << '\n';}
return 0;
}
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){
x1 =(-b + sqrt(temp))/2*a;
x2 = (-b - sqrt(temp))/2*a;
std::cout << "The two roots are: "<< x1 <<" and " << x2 << "\n";
}else{throw negative();}
}else{throw zero_division();}
}else{throw all_zero();}
}
Live Demo
Note that exceptions should be catched as reference, otherwise there will be object slicing when the exception is derived. And as in general you don't know what type of exception you will catch, you need to be careful to avoid that.
Alternatively you could use a more general exception type (roots_exception?) and instead of hardcoding the "what" pass it to the constructor when you throw it.
There is probably more you can improve, for which I suggest you https://codereview.stackexchange.com/.
PS: I tried to keep style aside, though one more thing you should change is to return the result from the function, instead of just printing it to the screen. If you want to use the result for other calcualtions you currently cannot. Perhaps you were puzzled how to return two values. std::pair makes that simple:
std::pair<double,double> roots(...) {
// ...
return {x1,x2};
}
and then:
try {
auto result = roots(a,b,c);
std::cout << "The two roots are: "<< result.first <<" and " << result.second << "\n";
}
My input:
Make sure the formula is correct. The /2*a part should be /(2*a).
Define an error category for your solver's errors and inherit more specific errors from that.
Remove unnessary tests (a== 0 && b== 0 && c==0). You already check if a == 0, so if a != 0 but b and c are, the solution will be 0, which should be valid.
Reverse the tests to not have to throw in an else. Throw early to not have deep nested if's.
Return the result, don't print it. I've added tweaks to make it possible to solve linear and complex equations too (in comments), but you can skip that if you want. This shows how you can return multiple values though.
Don't do forward declaration unless you really have to.
Read Why is using namespace std; considered bad practice?
More details in comments in the code
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <tuple> // std::tuple - used for returning multiple values here
struct solver_error : std::runtime_error { // your solver's error category
using std::runtime_error::runtime_error;
};
struct unknown_error : solver_error {
unknown_error() : solver_error("x is unknown") {}
};
struct linear_error : solver_error {
linear_error() : solver_error("cant solve linear equation") {}
};
struct complex_error : solver_error {
complex_error() : solver_error("cant solve complex equation") {}
};
// add more exceptions to the solver_error exception category if needed
// now returns two values and a bool to indicate if the solution is complex
std::tuple<double, double, bool> solve_for_x(double a, double b, double c) {
if(a == 0) throw linear_error(); // throw early
/* ... or solve it as a linear equation:
if(a == 0) {
if(b == 0) throw unknown_error(); // both a and b == 0, x is unknown
double res = -c / b;
return {res, res, false}; // only one x and not complex
}
*/
double div = 2 * a;
double temp = b * b - 4 * a * c;
if(temp < 0) throw complex_error();
/* ... or solve it as a complex equation
if(temp < 0) {
double sqr = sqrt(-temp); // sqrt of the positive temp instead
return {-b / div, sqr / div, true}; // real, imaginary and complex==true
}
*/
// real quadratic
double sqr = sqrt(temp);
double x1 = (-b + sqr) / div; // corrected formula (div = 2*a)
double x2 = (-b - sqr) / div; // corrected formula
return {x1, x2, false}; // return the two values and complex==false
}
int main() {
// make the user aware of what the coefficients are for
std::cout << "Enter the three coefficients a, b and c in the equation\n"
"ax^2 + bx + c = 0\n";
double a, b, c;
try {
// check that extracting the numbers succeeds
if(not(std::cin >> a >> b >> c)) throw std::runtime_error("input error");
// get the three return values via structured bindings
auto [first, second, complex] = solve_for_x(a, b, c);
std::cout << "x = ";
if(complex) // complex quadratic
std::cout << first << " ± " << second << 'i';
else if(first == second) // linear
std::cout << first;
else // real quadratic
std::cout << '{' << first << ',' << second << '}';
std::cout << '\n';
} catch(const solver_error& ex) {
// catching the generic error category by "const&"
std::cerr << "Solver error: " << ex.what() << '\n';
return 1;
} catch(const std::runtime_error& ex) {
std::cerr << ex.what() << '\n';
return 1;
}
}

Why is this exact exception thrown in my c++ code?

I am analyzing part of code that was part of my lectures.
I have managed to compile it but I cannot understand:
why does my program output "Wyjatek" and 0 instead of "WyjatekNieoznaczony"?
I was pretty sure WyjatekNieoznaczony() should be thrown because a=0 and b=0 as well. Right now i am a little bit confused.
Could you help me, please?
class Wyjatek {};
class WyjatekBledny : public Wyjatek {};
class WyjatekNieoznaczony : public Wyjatek {};
double f(double a, double b) {
if (b == 0) {
if (a == 0)
throw WyjatekNieoznaczony();
else
throw WyjatekBledny();
}
return a / b;
}
double g(double a, double b) throw (int) {
try {
return f(a, b);
}
catch (WyjatekBledny) {
cout << "Wyjatek bledny" << endl;
throw 1;
}
catch (Wyjatek) {
cout << "Wyjatek" << endl;
}
catch (WyjatekNieoznaczony) {
cout << "Wyjatek nieoznaczony" << endl;
throw;
}
return 0;
}
int main()
{
double a = 0, b = 0;
try {
cout << g(a, b) << endl;
}
catch (...)
{
cout << "Inny wyjatek" << endl;
}
system("pause");
return 0;
}
Yes indeed a WyjatekNieoznaczony is thrown, but at the catch site, catch (Wyjatek) { is a match (due to the inheritance) so it's caught there.
A catch site is more like an if else block in behaviour - with each catch possibility being considered in the order they are written - rather than a switch block where you can put the labels in any order you like.
Note also that it's a good idea to catch exceptions by const reference than by value, else you can suffer the pitfalls of object slicing.
If you enabled (and read) compiler warnings, you would've encountered the following diagnostic:
warning: exception of type 'WyjatekNieoznaczony' will be caught [...] by earlier handler for 'Wyjatek'.
This basically means that WyjatekNieoznaczony, by inheriting from Wyjatek, will be first caught by catch(Wyjatek) clause, since it's convertible. The problem is that due to object slicing, it will lose its Nieoznaczonyness.
What I suggest is to reorder the catch clauses so the possibility of slicing disappears (in this case):
catch (WyjatekBledny) {
cout << "Wyjatek bledny" << endl;
throw 1;
}
catch (WyjatekNieoznaczony) {
cout << "Wyjatek nieoznaczony" << endl;
throw;
}
catch (Wyjatek) {
cout << "Wyjatek" << endl;
}

why constructor is not getting call for second object in an array

Consider this program
#include <iostream>
using namespace std;
class sample
{
public:
sample()
{
cout << "consructor called" << endl;
throw 5;
}
void test()
{
cout << "Test function" << endl;
}
};
int main()
{
sample *s = nullptr;
try
{
s = new sample[5];
cout << "allocated" << endl;
}
catch(bad_alloc& ba)
{
cout << ba.what() << endl;
}
catch (const int& f)
{
cout << "catcting exception";
}
return 0;
}
I think the flow will be like this.
1. Allocate the memory for 5 object.
2. call the constructor for each object one by one.
But here while calling the constructor, i'm throwing an exception, which is handled. My doubt is why constructor is not getting called for second objects onwards??
The object creation will be in sequence, it can't create all five objects in one go. When the first object gets created your constructor will get called and as it throws exception, it will move control to exception handler block.
You exception Handler will print the appropriate message and have graceful exit.
Try your test removing throw 5;
The new simple[5] will allocate memory for the 5 simples, and then begin constructing them one by one. Since the first one does a throw 5, the other 4 do not get constructed.

How to check a function pointer exists

In C++, I'm trying to write a function with function pointers. I want to be able to throw an exception if a function pointer is passed for a function that does not exist. I tried to handle the function pointer like a normal pointer and check if it is null
#include <cstddef>
#include <iostream>
using namespace std;
int add_1(const int& x) {
return x + 1;
}
int foo(const int& x, int (*funcPtr)(const int& x)) {
if (funcPtr != NULL) {
return funcPtr(x);
} else {
throw "not a valid function pointer";
}
}
int main(int argc, char** argv) {
try {
int x = 5;
cout << "add_1 result is " << add_1(x) << endl;
cout << "foo add_1 result is " << foo(x, add_1) << endl;
cout << "foo add_2 result is " << foo(x, add_2) << endl; //should produce an error
}
catch (const char* strException) {
cerr << "Error: " << strException << endl;
}
catch (...) {
cerr << "We caught an exception of an undetermined type" << endl;
}
return 0;
}
but that doesn't seem to work. What is the best way to do this?
Checking for NULL is ok. But it is not possible to pass a pointer to a function that does not exist in the first place. So you don't have to worry about this. Although it is possible to just declare a function without defining it and pass the address of it. In that case you will get linker error.
It will automatically throw an error if you are passing pointer which does not exist, if you are declaring a pointer then you have to initialize it with null to avoid garbage value, so comparing with null will not serve any purpose.
you still you want to check then try to assign some function(like add, sub etc.), if it takes then ok , if not then it will show again error as previously mentioned.
#include<cstddef>
#include <iostream>
using namespace std;
int foo(const int& x, int (*funcPtr)(const int& x)) {
if (*funcPtr != NULL) {
return funcPtr(x);
}
else
{
cout << "not a valid function pointer";
}
}
If you want to 'throw' exception then you need to 'catch' it as well.
Your code is failing because of two reasons in short,
1) You are not checking value of function pointer.
2) You are not properly catching the thrown exception.

How to create exceptions?

So I have an upcoming assignment dealing with exceptions and using them in my current address book program that most of the homework is centered around. I decided to play around with exceptions and the whole try catch thing, and using a class design, which is what I will eventually have to do for my assignment in a couple of weeks. I have working code that check the exception just fine, but what I want to know, is if there is a way to standardize my error message function, (i.e my what() call):
Here s my code:
#include <iostream>
#include <exception>
using namespace std;
class testException: public exception
{
public:
virtual const char* what() const throw() // my call to the std exception class function (doesn't nessasarily have to be virtual).
{
return "You can't divide by zero! Error code number 0, restarting the calculator..."; // my error message
}
void noZero();
}myex; //<-this is just a lazy way to create an object
int main()
{
void noZero();
int a, b;
cout << endl;
cout << "Enter a number to be divided " << endl;
cout << endl;
cin >> a;
cout << endl;
cout << "You entered " << a << " , Now give me a number to divide by " << endl;
cin >> b;
try
{
myex.noZero(b); // trys my exception from my class to see if there is an issue
}
catch(testException &te) // if the error is true, then this calls up the eror message and restarts the progrm from the start.
{
cout << te.what() << endl;
return main();
}
cout <<endl;
cout << "The two numbers divided are " << (a / b) << endl; // if no errors are found, then the calculation is performed and the program exits.
return 0;
}
void testException::noZero(int &b) //my function that tests what I want to check
{
if(b == 0 ) throw myex; // only need to see if the problem exists, if it does, I throw my exception object, if it doesn't I just move onto the regular code.
}
What I would like to be able to do is make it so my what() function can return a value dependent on what type of error is being called on. So for instance, if I were calling up an error that looked a the top number,(a), to see if it was a zero, and if it was, it would then set the message to say that "you can't have a numerator of zero", but still be inside the what() function. Here's an example:
virtual const char* what() const throw()
if(myex == 1)
{
return "You can't have a 0 for the numerator! Error code # 1 "
}
else
return "You can't divide by zero! Error code number 0, restarting the calculator..."; // my error message
}
This obviously wouldn't work, but is there a way to make it so I'm not writing a different function for each error message?
Your code contains a lot of misconceptions. The short answer is yes, you can change what() in order to return whatever you want. But let's go step by step.
#include <iostream>
#include <exception>
#include <stdexcept>
#include <sstream>
using namespace std;
class DivideByZeroException: public runtime_error {
public:
DivideByZeroException(int x, int y)
: runtime_error( "division by zero" ), numerator( x ), denominator( y )
{}
virtual const char* what() const throw()
{
cnvt.str( "" );
cnvt << runtime_error::what() << ": " << getNumerator()
<< " / " << getDenominator();
return cnvt.str().c_str();
}
int getNumerator() const
{ return numerator; }
int getDenominator() const
{ return denominator; }
template<typename T>
static T divide(const T& n1, const T& n2)
{
if ( n2 == T( 0 ) ) {
throw DivideByZeroException( n1, n2 );
}
return ( n1 / n2 );
}
private:
int numerator;
int denominator;
static ostringstream cnvt;
};
ostringstream DivideByZeroException::cnvt;
In the first place, runtime_error, derived from exception, is the adviced exception class to derive from. This is declared in the stdexcept header. You only have to initialize its constructor with the message you are going to return in the what() method.
Secondly, you should appropriately name your classes. I understand this is just a test, but a descriptive name will always help to read and understand your code.
As you can see, I've changed the constructor in order to accept the numbers to divide that provoked the exception. You did the test in the exception... well, I've respected this, but as a static function which can be invoked from the outside.
And finally, the what() method. Since we are dividing two numbers, it would be nice to show that two numbers that provoked the exception. The only way to achieve that is the use of ostringstream. Here we make it static so there is no problem of returning a pointer to a stack object (i.e., having cnvt a local variable would introduce undefined behaviour).
The rest of the program is more or less as you listed it in your question:
int main()
{
int a, b, result;
cout << endl;
cout << "Enter a number to be divided " << endl;
cout << endl;
cin >> a;
cout << endl;
cout << "You entered " << a << " , Now give me a number to divide by " << endl;
cin >> b;
try
{
result = DivideByZeroException::divide( a, b );
cout << "\nThe two numbers divided are " << result << endl;
}
catch(const DivideByZeroException &e)
{
cout << e.what() << endl;
}
return 0;
}
As you can see, I've removed your return main() instruction. It does not make sense, since you cannot call main() recursively. Also, the objective of that is a mistake: you'd expect to retry the operation that provoked the exception, but this is not possible, since exceptions are not reentrant. You can, however, change the source code a little bit, to achieve the same effect:
int main()
{
int a, b, result;
bool error;
do {
error = false;
cout << endl;
cout << "Enter a number to be divided " << endl;
cout << endl;
cin >> a;
cout << endl;
cout << "You entered " << a << " , Now give me a number to divide by " << endl;
cin >> b;
try
{
result = DivideByZeroException::divide( a, b ); // trys my exception from my class to see if there is an issue
cout << "\nThe two numbers divided are " << result << endl;
}
catch(const DivideByZeroException &e) // if the error is true, then this calls up the eror message and restarts the progrm from the start.
{
cout << e.what() << endl;
error = true;
}
} while( error );
return 0;
}
As you can see, in case of an error the execution follows until a "proper" division is entered.
Hope this helps.
You can create your own exception class for length error like this
class MyException : public std::length_error{
public:
MyException(const int &n):std::length_error(to_string(n)){}
};
class zeroNumerator: public std::exception
{
const char* what() const throw() { return "Numerator can't be 0.\n"; }
};
//...
try
{
myex.noZero(b); // trys my exception from my class to see if there is an issue
if(myex==1)
{
throw zeroNumerator(); // This would be a class that you create saying that you can't have 0 on the numerator
}
}
catch(testException &te)
{
cout << te.what() << endl;
return main();
}
You should always use std::exception&e. so do
catch(std::exception & e)
{
cout<<e.what();
}
You should consider a hierarchy of classes.
The reason for it might not be obvious when trying to use exceptions just for transferring a string, but actual intent of using exceptions should be a mechanism for advanced handling of exceptional situations. A lot of things are being done under the hood of C++ runtime environment while call stack is unwound when traveling from 'throw' to corresponded 'catch'.
An example of the classes could be:
class CalculationError : public std::runtime_error {
public:
CalculationError(const char * message)
:runtime_error(message)
{
}
};
class ZeroDeviderError : public CalculationError {
public:
ZeroDeviderError(int numerator, const char * message)
: CalculationError(message)
, numerator (numerator)
{
}
int GetNumerator() const { return numerator; }
private:
const int numerator;
};
Providing different classes for the errors, you give developers a chance to handle different errors in particular ways (not just display an error message)
Providing a base class for the types of error, allows developers to be more flexible - be as specific as they need.
In some cases, they might want to be specific
} catch (const ZeroDividerError & ex) {
// ...
}
in others, not
} catch (const CalculationError & ex) {
// ...
}
Some additional details:
You should not create objects of your exceptions before throwing in the manner you did. Regardless your intention, it is just useless - anyway, you are working with a copy of the object in the catch section (don't be confused by access via reference - another instance of the exception object is created when throwing)
Using a const reference would be a good style catch (const testException &te) unless you really need a non-constant object.
Also, please note that the type (classes) used for exceptions are not permitted to throw exceptions out of their copy constructors since, if the initial exception is attempted to be caught by value, a call of copy constructor is possible (in case is not elided by the compiler) and this additional exception will interrupt the initial exception handling before the initial exception is caught, which causes calling std::terminate.
Since C++11 compilers are permitted to eliminate the copying in some cases when catching, but both the elision is not always sensible and, if sensible, it is only permission but not obligation (see https://en.cppreference.com/w/cpp/language/copy_elision for details; before C++11 the standards of the language didn’t regulate the matter).
Also, you should avoid exceptions (will call them the additional) to be thrown out of constructors and move constructors of your types (classes) used for exceptions (will call them initial) since the constructors and move constructors could be called when throwing objects of the types as initial exceptions, then throwing out an additional exception would prevent creation of an initial exception object, and the initial would just be lost. As well as an additional exception from a copy constructor, when throwing an initial one, would cause the same.