Base class of everything in c++ [duplicate] - c++

This question already has answers here:
Why is there no base class in C++?
(6 answers)
Closed 6 years ago.
In Java, the Object class is the base class of all classes. Is there any such class in C++ as well?
My motivation for the question is:
try
{
if (something) throw int(a);
if (something) throw char(b);
if (something) throw float(c);
}
catch(...)
{
handle
}
Is there any other way to handle all these exceptions using single catch block apart from this?

There is no universal base class in C++.
Exception classes should usually derive from std::exception, so that catch(const std::exception&) can be used.
catch(...) catches any exception object type (including primitive types). It can be rethrown inside the catch block with throw;:
try
{
if (something) throw int(a);
if (something) throw char(b);
if (something) throw float(c);
}
catch(...)
{
if(stillFailed) throw; // throws the same exception again
}
It is also possible to get a std::exception_ptr object which represents the thrown object (of unknown type), using std::current_exception(), inside the catch(...) block. It can then be compared for equality with other std::exception_ptr objects, or rethrown from another function using std::rethrow_exception(). See http://en.cppreference.com/w/cpp/header/exception . There is no way to get direct access to the exception object, because its type is unknown.

The most universal type for such cases is std::string (after all, even the most complex programs are simply arrays of characters).
Encode your object into a text form and parse/interpret it on the handling side.
template<class T>
std::string toString(const T& x);
try
{
if (something) throw toString(int(a));
if (something) throw toString(char(b));
if (something) throw toString(float(c));
}
catch(const std::string& ex)
{
decode and handle
}
However, if you'd be willing to take this approach, then C++ is not the right language for doing your programming - better switch to a text-oriented or dynamic language.

No,there any other way to handle all these exceptions using single catch block apart.
different catch blocks are needed to handle different data types throw.
like
for int
catch(int m)
for char
(char m)
etc.

Related

Copy std::exception object to a struct member in C++ [duplicate]

I have an API which internally has some exceptions for error reporting. The basic structure is that it has a root exception object which inherits from std::exception, then it will throw some subclass of that.
Since catching an exception thrown in one library or thread and catching it in another can lead to undefined behavior (at least Qt complains about it and disallows it in many contexts). I would like to wrap the library calls in functions which will return a status code, and if an exception occurred, a copy of the exception object.
What is the best way to store an exception (with it's polymorphic behavior) for later use? I believe that the c++0x future API makes use of something like this. So what is the best approach?
The best I can think of is to have a clone() method in each exception class which will return a pointer to an exception of the same type. But that's not very generic and doesn't deal with standard exceptions at all.
Any thoughts?
EDIT: It seems that c++0x will have a mechanism for this. It is described as "library magic". Does that mean that is doesn't require any of the language features of c++0x? if not, are there any implementations which are compatible with c++03?
EDIT: Looks like boost has an implementation of exception copying. I'll keep the question open for any non boost::copy_exception answers.
EDIT: To address j_random_hacker's concerns about the root cause of the exception being an out of memory error. For this particular library and set of exceptions, this is not the case. All exceptions derived from the root exception object represent different types of parsing errors caused by invalid user input. Memory related exceptions will simply cause a std::bad_alloc to be thrown which is addressed separately.
As of C++11, this can be done using std::exception_ptr.
(I use this in a class that makes an std::thread interruptible provided that the underlying thread implementation is a POSIX thread. To handle exceptions that may be thrown in the user's code - which causes problems if they are thrown in a certain critical section of my implementation - I store the exception using std::exception_ptr, then throw it later once the critical section has completed.)
To store the exception, you catch it and store it in the ptr variable.
std::exception_ptr eptr;
try {
... do whatever ...
} catch (...) {
eptr = std::current_exception();
}
You can then pass eptr around wherever you like, even into other threads (according to the docs - I haven't tried that myself). When it is time to use (i.e. throw) it again, you would do the following:
if (eptr) {
std::rethrow_exception(eptr);
}
If you want to examine the exception, you would simply catch it.
try {
if (eptr) {
std::rethrow_exception(eptr);
}
} catch (const std::exception& e) {
... examine e ...
} catch (...) {
... handle any non-standard exceptions ...
}
You have what would be what I think is your best, only answer. You can't keep a reference to the original exception because it's going to leave scope. You simply have to make a copy of it and the only generic way to do that is with a prototype function like clone().
Sorry.
You're allowed to throw anything, including pointers. You could always do something like this:
throw new MyException(args);
And then in the exception handler store the caught pointer, which will be fully polymorphic (below assuming that MyException derives from std::exception):
try {
doSomething(); // Might throw MyException*
} catch (std::exception* pEx) {
// store pEx pointer
}
You just have to be careful about memory leaks when you do it this way, which is why throw-by-value and catch-by-reference is normally used.
More about catch-by-pointer: http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.8
The reason why catching an exception thrown in one library and catching it in another can lead to undefined behavior is that these libraries could be linked with different Runtime libraries. If you will return exception from a function instead of throwing it you will not avoid that problem.
My utility library has an AnyException class that is basically the same as boost::any without the casting support. Instead, it has a Throw() member that throws the original object stored.
struct AnyException {
template<typename E>
AnyException(const E& e)
: instance(new Exception<E>(e))
{ }
void Throw() const {
instance->Throw();
}
private:
struct ExceptionBase {
virtual void Throw() const =0;
virtual ~ExceptionBase() { }
};
template<typename E>
struct Exception : ExceptionBase {
Exception(const E& e)
: instance(e)
{ }
void Throw() const {
throw std::move(instance);
}
private:
E instance;
};
ExceptionBase* instance;
};
This is a simplification, but that's the basic framework. My actual code disables copying, and has move semantics instead. If needed, you can add a virtual Clone method to the ExceptionBase easily enough... since Exception knows the original type of the object, it can forward the request onto the actual copy constructor, and you immediately have support for all copiable types, not just ones with their own Clone method.
When this was designed, it was not meant for storing caught exceptions... once an exception was thrown, it propagated as normal, so out-of-memory conditions were not considered. However, I imagine you could add an instance of std::bad_alloc to the object, and store it directly in those situations.
struct AnyException {
template<typename E>
AnyException(const E& e) {
try {
instance.excep = new Exception<E>(e);
has_exception = true;
} catch(std::bad_alloc& bad) {
instance.bad_alloc = bad;
bas_exception = false;
}
}
//for the case where we are given a bad_alloc to begin with... no point in even trying
AnyException(const std::bad_alloc& bad) {
instance.bad_alloc = bad;
has_exception = false;
}
void Throw() const {
if(has_exception)
instance.excep->Throw();
throw instance.bad_alloc;
}
private:
union {
ExceptionBase* excep;
std::bad_alloc bad_alloc;
} instance;
bool has_exception;
};
I haven't actually tested that second bit at all... I might be missing something glaringly obvious that will prevent it from working.

Returning a class in a function with exception handling

Let's say I have function that is mean to return a class, however, I wish to use exception handling when calling the constructor. Issue is, in the case of an exception the class I wanted to return is out of scope and I have nothing to return:
myclass GetClass() {
try {
myclass classtoreturn(7);
return classtoreturn;
} catch ( const std::exception& ex ) {
//
} catch ( const std::string& str ) {
//
} catch (...) {
//
}
return ??;
}
However, if I declare the class outside of the try/catch, I'm going to have the issue of an un-initialized class to return:
myclass GetClass() {
myclass classtoreturn;
try {
classtoreturn(7);
return classtoreturn;
} catch ( const std::exception& ex ) {
//
} catch ( const std::string& str ) {
//
} catch (...) {
//
}
return classtoreturn; //Unitialized!
}
My first instict was to return a pointer instead and return a NULL pointer in the event of an exception, but then the pointer would be pointing to an out of scope class which still is no good. Seems like this would be a common issue but I haven't stumbled upon a solution.
Also, the actual application can be seen here, where I am trying to return the gpsmm class to my main function so it can be later passed as a pointer to a polling function.
Thanks!
OK, reading some responses now I'm thinking it makes sense to catch the exception at the caller, however, I think this just propogates the issue to the caller:
void main() {
try{
myclass classforuse{ GetClass() };
} catch (...) {
//
}
//Want to do something with "classforuse" but it's out of scope!
}
As I understand it the class will beconstructed when I declare it, so there's no way for me to construct a class from within a try{} and then use it outside the scope of that same try{} without using std/boost::optional. Is that correct? I think the boost libraries will be my only option unless I find a practical means to use the class from within the same try{}. Thanks
There are few ways you could handle this. The first is to change the return the return type of the function and instead of returning the class by value pass it by std::unique_ptr. std::unique_ptr can be null so if there is an exception you can return a null unique_ptr otherwise you just return the unique_ptr to the object you created.
The other option is to use boost::optional or std::optional. You can use boost::optional right now but std::optional is a C++17 feature so it's availability is limited. Personally I like the optional approach better as it more describes the situation just by its type. optional also has the additional benefit that there is no dynamic memory allocation.
Lastly you could not recover and have the function throw. This will signal to the caller that something happened and they did not get an object returned.
My understanding of your question is that, in the event of an exception, your function is not able to fulfill it's obligation to return a valid myclass object and you are not sure how to handle it. The first solution to throw an exception, perhaps the one that caused it to fail. While inside a catch block, you can use an empty throw; statement to rethrow the same exception.
catch(const std::exception & err) {
// do whatever it is you need to do (logging?)
throw; // this statement throws 'err' again
}
I don't know if you expect to do anything with those exceptions (your catch blocks are empty, but it might be for brevity) but normally, if you can't fix the problem here, don't try to catch the exception. Just remove the whole try/catch and let the exception propagate.
If throwing from your function isn't acceptable for your case then you will have to change your function to return something other than myclass. If you have access to C++17 consider using std::optional or a similar wrapper.
The catch looks misplaced. Consider catching exceptions in the client code or re-throwing. Otherwise, the function should be able to recover and return a successfully created object.

C++ how to get handle to exception thrown in generic catch handler

Is there any way to get handle to exception thrown inside generic catch block.
try
{
throw ;
}
catch(...)
{
// how to get handle to exception thrown
}
Thanks
You can use std::current_exception.
Rearranging from cppreference:
#include <string>
#include <exception>
#include <stdexcept>
int main()
{
eptr;
try {
std::string().at(1); // this generates an std::out_of_range
} catch(...) {
std::exception_ptr eptr = std::current_exception(); // capture
}
}
Inside the catch(...) block, the current exception has been captured by the exception_ptr eptr. The exception object referenced by an std::exception_ptr remains valid as long as there remains at least one std::exception_ptr that is referencing it: std::exception_ptr is a shared-ownership smart pointer.
The problem is that is C++, an exception is allowed to be of any type and not only a subclass of std::exception. That's the reason why the common idiom is to use only exception classes derived from std::exception to have a coherent interface.
You can always as suggested by #PaoloM use std::current_exception(). But it has some limitations that make it hard to use, because to be allowed to represent any type of exception it is a std::exception_ptr that only can (ref. in cpluscplus.com):
be default-constructed (acquiring a null-pointer value).
be copied, including being copied a null-pointer value (or nullptr).
be compared against another exception_ptr object (or nullptr) using either operator== or operator!=, where two null-pointers are always considered equivalent, and two non-null pointers are considered equivalent only if they refer to the same exception object.
be contextually convertible to bool, as false if having null-pointer value, and as true otherwise.
be swapped, and being destructed.
Performing any other operation on the object (such as dereferencing it), if at all supported by the library implementation, causes undefined behavior.
If you want to be able to to serious things with an exception, you should use dedicated exception handlers:
try
{
throw ;
}
catch (MyException& a) {
// Ok, it is a know type and I know how to deal with it
}
catch (std::exception& e) {
// it is a subclass of std::exception, I can at least use its what() method
catch(...)
{
// I can get a std::exception_ptr from current_exception, but cannot know what to do with it
}

The parameter for the 'catch' [duplicate]

This question already has answers here:
catch exception by pointer in C++
(5 answers)
Closed 9 years ago.
I read the "Programming: Principles and Practice using C++" book (Bjarne Stroustrup). Sometimes the author writes:
catch (runtime_error e)
but sometimes he writes:
catch (runtime_error& e)
As I know, the first variant creates the copy of source, but the second uses the link. Or am I mistaken? Is this not important for the "catch" in this case?
I would have expected that most of the time, he would use:
catch ( runtime_error const& e )
The difference between catch by value and catch by reference is
exactly the same as pass by value and pass by reference for
a function parameter. The most important difference is that
when catching by reference, the dynamic type can be
a derived type, by value will result in slicing (because of the
copy).
Also, if you catch by non-const reference, and modify the
exception object, then rethrow, it is the modified object which
will propagate.
In order to avoid unnecessary copies AND slicing, you should always catch the exception by reference. Especially in the cases, when you plan to re-throw; it.
Catch by value
catch (runtime_error e)
versus catch by reference
catch (runtime_error& e)
You'd use the later when you have (usualy polymorphic) exception class hierarchy and you want to catch exceptions of all the derived types in a single catch clause.
For example, all the exception classes from the standard library derive from std::exception, so you can do something like this:
try {
int i;
std::cin >> i;
switch (i) {
case 1: throw std::range_error();
case 2: throw std::overflow_error();
case 3: throw std::undefflow_error();
default: throw std::logic_error();
}
} catch (std::exception& e) {
// handle all the exceptions the same way,
// but print a diagnostic message polimorphicaly
std::cout << "I caught: " << e.what() << '\n';
}
If, instead by reference, you'd catch by value, you'd always catch a std::exception, sliced off of the derived part of the object.
You should always catch by reference; there is absolutely no reason to catch by value.
Don't trust everything that is written. ;-)

std exceptions inviting unsafe usage?

It is recommended that you always throw something derived from std::exception and there are a few predefines specialisations such as std::runtime_error
std::exception's interface is given in terms of non-throwing accessors. Great. Now look at the constructor for std::runtime_error
class runtime_error : public exception {
public:
explicit runtime_error (const string &);
};
So if I do this
try {
foo ();
}
catch (...) {
throw std :: runtime_error ("bang");
}
it's entirely possible that foo threw because it's out of memory, in which case constructing the string argument to runtime_error can also throw. This would be a throw-expression which itself also throws: won't this will call std::terminate?
Doesn't this mean we should always do this instead:
namespace {
const std :: string BANG ("bang");
}
...
try {
foo ();
}
catch (...) {
throw std :: runtime_error (BANG);
}
BUT WAIT this won't work either, will it? Because runtime_error is going to copy its argument, which may also throw...
...so doesn't this mean that there is no safe way to use the standard specialisations of std::exception, and that you should always roll your own string class whose constructor only fails without throwing?
Or is there some trick I'm missing?
I think your main problem is that you are doing catch(...) and translating to a std::runtime_error thereby losing all type information from the original exception. You should just rethrow with throw().
Practically, if you are short of memory you are likely have a bad_alloc exception thrown at some point and there's not a lot else you can - or should - do. If you want to throw an exception for a reason other than an allocation failed then you are not likely to have a problem constructing a sensible exception object with meaningful contextual information. If you hit a memory issue while formatting your exception object there's not a lot you can do other than propagate the memory error.
You are right that there is a potential problem if you construct a new string object to construct an exception, but if you want to format a message with context this can't be avoided in general. Note that the standard exception objects all have a const char* constructor (as of last week) so if you have a const char* that you want to use you don't have to construct a new std::string object.
std::runtime_error must copy it's argument, but not necessarily as a new string object. There could be an area of statically allocated memory which it can the contents of its argument to. It only has to fulfil the what() requirements which only requires returning a const char *, it doesn't have to store a std::string object.
This would be a throw-expression which itself also throws: won't this
will call std::terminate?
No, it wouldn't. It would just throw the exception about insufficient memory. The control will not reach the outer throw part.
BUT WAIT this won't work either, will it? Because runtime_error is
going to copy its argument, which may also throw...
Exception classes with a throwing copy-constructors are as evil as throwing destructors. Nothing that can really be done about it.
std::runtime_error is designed to treat the usual runtime errors, not
out of memory or other such critical exceptions. The base class
std::exception does not do anything which may throw; nor does
std::bad_alloc. And obviously, remapping std::bad_alloc into an
exception which requires dynamic allocation to work is a bad idea.
The first thing is what would you want to do if you happen to have a bad_alloc exception because you're out of memory?
I'd say in a classic C++ program, you'd want to have the program somehow trying to tell you what happened and then terminates.
In a classic C++ program you'd then let the bad_alloc exception propagate to the main section of the program. The main will contain an arragement of try/catch like this:
int main()
{
try
{
// your program starts
}
catch( const std::exception & e )
{
std::cerr << "huho something happened" << e.what() << std::endl;
}
catch( ... )
{
std::cerr << "huho..err..what?" << std::endl;
}
}
you'll only use catch( ... ) inside the main and at the starting functions of threads. Contrary to some other languages like Java you're not expected to catch all possible exceptions locally. You just let them propagate until you catch them where you wanted to.
Now if you have code that specifically must check std::bad_alloc, you should only catch( const std::bad_alloc & ) locally. And there it should maybe wise to do something else rather than just rethrow another exception.
I found in The C++ Programming Language ยง14.10 also that the C++ exception-handling mechanism keeps a bit of memory to itself for holding exceptions, so that throwing a standard library exception will not throw an exception by itself. Of course it is possible also to let the exception-handling mechanism run out of memory if you really code something perverted.
So, to sum up, if you do nothing and let big exceptions like bad_alloc propagate nicely where you want to catch them, in my opinion you're safe. And you should not use catch( ... ) or catch(const std::exception & ) anywhere except in the main function and in the starting functions of threads.
Catching all exceptions to rethrow a single exception is really the last thing to do. You lose every advantages you got with the C++ exception-handling mechanism.