try and catch, 2 classes - c++

I have a function using try-catch. so I want use and another class to print out different kind of messages. What should I do?
I use namespace std. I'm new at this an not familiar with using namespace std. Please guide me thanks.
SparseException::SparseException ()
{ }
SparseException::SparseException (char *message)
{ }
void SparseException::printMessage () const
{
// ...
}
try
{
//did some stuffs here.
}
catch (exception e)
{
char *message = "Sparse Exception caught: Element not found, delete fail";
SparseException s (message);
s.printMessage();
}

Derive your exception class from std::exception and override what(). Remove your function printMessage and implement (override):
virtual const char* what() const throw();
In C++11 this function has this signature:
virtual const char* what() const noexcept;
Then your catch clause and printing of exception's reason can look like this:
catch (const std::exception& e)
{
std::cerr << "exception caught: " << e.what() << '\n';
}

Or if you are going to throw only your exception, you can simply do this:
SparseException::SparseException ()
{ }
SparseException::SparseException (char *message)
{ }
void SparseException::printMessage () const
{
// ...
}
try
{
//did some stuffs here.
//Possibly
//throw SparseException();
//or
//throw SparseException("Some string");
//Make sure you can throw only objects of SparseException type
}
catch (SparseException e)
{
e.printMessage();
}
If the line with throw is executed, the result of try block will be terminated and the catch block will execute, where e is the object you have thrown.

Related

Why is my C++ exception not being caught?

My code throws std::runtime_error, but doesn't catch it in the catch block. Instead it just calls std::terminate or, if I declared an exception-specifier on a function, calls std::unexpected.
The code simplifies down to:
void myfunc()
{
throw new std::runtime_error("always throw");
}
int main()
{
try {
myfunc();
} catch (std::runtime_error &err) {
std::cerr << "intentionally ignored exception: " << err.what() << std::endl;
return 0;
}
std::cerr << "unreachable?" << std::endl;
return 1;
}
Similarly, if I add a throw specifier on my function, I crash out with std::unknown.
void myfunc() throw (std::runtime_error)
{
throw new std::runtime_error("always throw");
}
You slipped in a Java-ism:
throw new std::runtime_error("always throw")
^^^
This causes the catch clause not to match, because it matches by type and you throw std::runtime_error*, i.e. a pointer to a std::runtime_error. It's expecting a plain std::runtime_error by-reference.
You could (untested) catch your original exception with
catch (std::runtime_error * exc) /* don't do this */
but you shouldn't do that.
Instead skip the new; throw your exception directly and write:
void myfunc()
{
throw std::runtime_error("always throw");
}
C++ is smart enough that if you catch the exception by-reference it won't get copied around.
Also, as #KonradRudolph points out in the comments, you should catch by const-reference:
catch (const std::runtime_error &err)

Catching strings for output

I have a try catch statement in my main function
try
{
app.init();
}
catch(std::string errorMessage)
{
std::cout << errorMessage;
return 1;
}
but when I throw "SOME_ERROR"; The console output is simply
terminate called after throwing an instance of 'char const*'
Aborted (core dumped)
How can I make errorMessage output to the console?
Please do not throw anything which is not derived from std::exception.
An exemption might be an exception intended to terminate the program (providing an internal state, though)
You either intend to throw std::string OR catch const char*:
throw std::string("error")
catch(const char* message)
However as pointed out, it's better just to derive from std::exception:
#include <iostream>
// must include these
#include <exception>
#include <stdexcept>
struct CustomException : std::exception {
const char* what() const noexcept {return "Something happened!\n";}
};
int main () {
try {
// throw CustomException();
// or use one already provided
throw std::runtime_error("You can't do that, buddy.");
} catch (std::exception& ex) {
std::cout << ex.what();
}
return 0;
}
You need to derive something from std::exception. <--if you want memory safety
It has a method: virtual const char* ::std::exception::what() const noexcept;
Build your char* you want to see in the constructor, store it, return it for what() then free it in the destructor for memory safe exceptions.

How to supplement boost::exception with a proper what() function

I like boost::exception quite a bit, but I'm quite bothered it does not provide a proper what() function out of the box. Now don't get confused, it does have a nice boost::diagnostic_information that contains all the information I would like to see in my hypothetic what() function but since boost::exception does not inherit from std::exception the what() function I get if I multiple inherit (as suggested from the tutorial, see line below) is the default useless what() from the std::exception base that explains nothing about the exception.
struct my_exception: virtual std::exception, virtual boost::exception { };
Now obviously I tried to override what() and make it return boost::diagnostic_information but somehow it just does not work, so I'm a bit puzzled. That might be because it would loop but I'm not quite sure.
PS: The reason I want to implement what() right is that it is shown by default by a lot of tools if your program dies from them (e.g. the gnu compiler will show a nice fatal error, and display what(), boost unit tests tools etc.).
Here's a link to the test code below
#include <boost/exception/all.hpp>
struct my_exception: virtual std::exception, virtual boost::exception {};
struct my_exception2: virtual std::exception, virtual boost::exception {
virtual const char* what() const throw() {
return "WHAT";
}
};
struct my_exception3: virtual std::exception, virtual boost::exception {
virtual const char* what() const throw() {
return boost::diagnostic_information(this).c_str();
}
};
int main() {
try {
BOOST_THROW_EXCEPTION(my_exception());
} catch (const std::exception& e){
std::cout << e.what() << std::endl;
//This is useless ___ std::exception
}
try {
BOOST_THROW_EXCEPTION(my_exception());
} catch (const boost::exception& e){
std::cout << boost::diagnostic_information(e) << std::endl;
//This is what I'd like to see ___ main.cpp(39): Throw in function int main() ___ Dynamic exception type: boost::exception_detail::clone_impl ___ std::exception::what: std::exception
}
try {
BOOST_THROW_EXCEPTION(my_exception2());
} catch (const std::exception& e){
std::cout << e.what() << std::endl;
//Overriding what usually works ___ WHAT
}
try {
BOOST_THROW_EXCEPTION(my_exception3());
} catch (const std::exception& e){
std::cout << e.what() << std::endl;
//But somehow here it does not work ___ Unknown exception.
}
}
First, boost::diagnostic_information takes an exception by (const) reference, and this is a pointer:
return boost::diagnostic_information(*this).c_str();
^-- here
Second, once you've fixed that, as you've correctly anticipated this results in infinite recursion as boost::diagnostic_information calls std::exception::what(). It is possible to work around this with a guard member or something similar:
struct my_exception3: std::exception, boost::exception {
mutable bool in_what = false;
virtual const char* what() const throw() {
struct g { bool &b; ~g() { b = false; } } guard{in_what};
return in_what ? "WHAT" : (in_what = true, boost::diagnostic_information(*this).c_str());
}
};
Finally, you're using c_str from a destructed temporary string. I'll leave the solution to that problem as an exercise.
And the winner is...
namespace boost {
char const * diagnostic_information_what( boost::exception const & e ) throw();
}

How to throw an exception by its run-time type?

I want to call a function that may throw an exception. If it does throw an exception, I want to catch it and pass the exception object to a handler function. The default implementation of the handler function is simply to throw the exception. Here is whittled-down code to illustrate the issue:
struct base_exception : exception {
char const* what() const throw() { return "base_exception"; }
};
struct derived_exception : base_exception {
char const* what() const throw() { return "derived_exception"; }
};
void exception_handler( base_exception const &e ) {
throw e; // always throws a base_exception object even if e is a derived_exception
}
int main() {
try {
throw derived_exception();
}
catch ( base_exception const &e ) {
try {
cout << e.what() << endl; // prints "derived_exception" as expected
exception_handler( e );
}
catch ( base_exception const &e ) {
cout << e.what() << endl; // prints "base_exception" due to object slicing
}
}
}
However, the throw e in exception_handler() throws a copy of the static type of the exception, i.e., base_exception. How can I make exception_handler() throw the actual exception having the correct run-time type of derived_exception? Or how can I redesign things to get what I want?
You can put a throw_me virtual function in the base exception class, and have every derived class override it. The derived classes can throw the proper most derived type, without slicing. Even though the function has the same definition in each class, they're not the same - the type of *this is different in each case.
struct base_exception : exception
{
char const* what() const throw() { return "base_exception"; }
virtual void throw_me() const { throw *this; }
};
struct derived_exception : base_exception
{
char const* what() const throw() { return "derived_exception"; }
virtual void throw_me() const { throw *this; }
};
void exception_handler( base_exception const &e ) {
e.throw_me();
}
You can use throw; to re-throw the exception that was caught. You could also use a template.
template<typename T> void rethrow(const T& t) { throw t; }
Throw by value, catch by reference. It'll save you a lot of headaches.
What you are looking for is called "propagating" the exception. To do so, you have to use the throw keyword without parameters inside the catch block. It will not copy the exception and the exception will be caught by the next catch block on its way or will make your program abort if it's not caught again.

How to simulate inner exception in C++

Basically I want to simulate .NET Exception.InnerException in C++. I want to catch exception from bottom layer and wrap it with another exception and throw again to upper layer. The problem here is I don't know how to wrap the catched exception inside another exception.
struct base_exception : public std::exception
{
std::exception& InnerException;
base_exception() : InnerException(???) { } // <---- what to initialize with
base_exception(std::exception& innerException) : InnerException(innerException) { }
};
struct func1_exception : public base_exception
{
const char* what() const throw()
{
return "func1 exception";
}
};
struct func2_exception : public base_exception
{
const char* what() const throw()
{
return "func2 exception";
}
};
void func2()
{
throw func2_exception();
}
void func1()
{
try
{
func2();
}
catch(std::exception& e)
{
throw func2_exception(e); // <--- is this correct? will the temporary object will be alive?
}
}
int main(void)
{
try
{
func1();
}
catch(base_exception& e)
{
std::cout << "Got exception" << std::endl;
std::cout << e.what();
std::cout << "InnerException" << std::endl;
std::cout << e.InnerException.what(); // <---- how to make sure it has inner exception ?
}
}
In the above code listing I am not sure how to initialize the "InnerException" member when there is no inner exception. Also I am not sure whether the temporary object that is thrown from func1 will survive even after func2 throw?
Since C++ 11 you have new options:
You can use std::exception_ptr.
The exception is then preserve until last exception_ptr to this
exception is destroyed.
struct base_exception : public std::exception
{
std::exception_ptr InnerException;
base_exception() {}
base_exception(std::exception& innerException)
: InnerException(std::make_exception_ptr(innerException))
{}
};
Or you can simply use std::nested_exception.
You should also take a look at boost exception for an alternative solution to wrapping.
Also I am not sure whether the
temporary object that is thrown from
func1 will survive even after func2
throw?
No. Unless you rethrow the exception with throw;. You could implement this if you'd allow only some (limited) set of exception types.
//inversion of the problem :)
struct base_exception : public std::exception
{
std::list<base_exception*> snowball;
base_exception() { }
void add(base_exception* e) { snowball.push_back(e); }
};
void func2()
{
func2_exception e;
e.add(new func2_exception());
throw e;
}
void func1()
{
try
{
func2();
}
catch(base_exception& e)
{
e.add(new func1_exception());
throw e;
}
}
int main(void)
{
try
{
func1();
}
catch(base_exception& e)
{
std::cout << "Got exception" << std::endl;
//print info in the direct order of exceptions occurence
foreach(base_exception* exception, e.snowball)
{
std::cout << exception->what();
std::cout << "next exception was:" << std::endl;
}
}
}
hmmmm...
One problem with the inner exception is the possibility to throw it again while maintaining polymorphic behaviour.
This can be (somewhat) alleviate by actually managing the exception lifetime yourself and providing polymorphic copies.
// Base class
class exception: virtual public std::exception, private boost::noncopyable
{
public:
virtual exception* clone() const = 0;
virtual void rethrow() const = 0; // throw most Derived copy
};
// ExceptionPointer
class ExceptionPointer: virtual public std::exception
{
public:
typedef std::unique_ptr<exception> pointer;
ExceptionPointer(): mPointer() {}
ExceptionPointer(exception* p): mPointer(p) {}
ExceptionPointer(pointer p): mPointer(p) {}
exception* get() const { return mPointer.get(); }
void throwInner() const { if (mPointer.get()) mPointer->rethrow(); }
virtual char* what() const { return mPointer.get() ? mPointer->what() : 0; }
private:
pointer mPointer;
};
How to use ?
try
{
// some code
}
catch(exception& e)
{
throw ExceptionPointer(e.clone());
}
// later on
try
{
}
catch(ExceptionPointer& e)
{
e.throwInner();
}
As stated by others, boost::exception is a nice option. However, like all options that use a common base class approach, they rely on all thrown exceptions being derived from that base class. If your intermediary catch handlers need to add information to an exception from a third party library it won't work.
An option that might be sufficient is to have intermediary catch handlers like this:
catch (std::exception& ex)
{
std::string msg = ex.what();
msg.append(" - my extra info");
ex = std::exception(msg.c_str()); // slicing assignment
throw; // re-throws 'ex', preserving it's original type
}
This only works for implementations of std::exception that provide a constructor taking a string parameter (e.g. VC++). The std::exception constructor taking a string is a non-standard extension.