C++ throw dereferenced pointer - c++

What is the type of the exception object in the following thrown:
Question1> range_error r("error"); throw r;
Answer1> an object of range_error
Question2> exception *p = &r; throw *p;
Answer2> a sliced object of exception
Question3> exception *p = &r; throw p;
Answer3> a pointer pointing to range_error is thrown. The capture-handling can access the range_error member functions through dynamic binding.
Do I get these question right?
// Updated and Compiled and Run on VS2010
#include <iostream>
using namespace std;
class ExClassA
{
public:
virtual void PrintMe() const
{
cout << "ExClassA" << endl;
}
};
class ExClassB : public ExClassA
{
public:
virtual void PrintMe() const
{
cout << "ExClassB" << endl;
}
};
int main(int argc, char* argv[])
{
ExClassB exClassB;
ExClassA *p = &exClassB;
try
{
throw *p;
}
catch (const ExClassA& e)
{
e.PrintMe();
}
try
{
throw p;
}
catch (const ExClassA* e)
{
e->PrintMe();
}
}
The first try-catch of above program prints "ExClassA"
The second try-catch of above program prints "ExClassB"

Throwing an object always results in the thrown object being a copy of the object you threw, based on the static type of that object. Thus your first two answers are correct.
The third one is a little more complicated. If you catch(range_error*) you won't catch the exception because the types don't match. If you catch(exception*) you won't be able to access members of range_error in the caught pointer; you can dynamic_cast that pointer back to a range_error pointer though.

I think you are right in all three. The type of the thrown object (IIRC) is the static type of the object being thrown. I would have to dig into the standard for a while to find the exact quotes, but a simple example seems to confirm this:
struct base {};
struct derived : base {};
void t() {
derived d;
base * b = &d;
throw *b;
}
int main() {
try {
t();
} catch ( derived const & ) {
std::cout << "derived" << std::endl;
} catch ( base const & ) {
std::cout << "base" << std::endl;
}
}
If the dynamic type of the object being thrown was used, then *b would have type derived and the first catch would succeed, but empirically the second catch is executed (g++).
In the last case, the object thrown is a pointer to exception that refers to a range_error object. The slight difference is again what can be caught, the compiler will not catch in a catch (range_error*) block. The answer is correct, but I would have specified the type of the pointer, as much as the type of the pointee. (The type of the pointer is somehow implicit in the answer)

All three answers are correct. Just note that you'll have to catch a
pointer type in the third case.
The usual way to throw an exception is:
throw range_error("error");
At the throw site, you normally know the exact type of exception you
want to throw. About the only exception I can think of is when the
exception was passed in as an argument, e.g.:
void f( std::exception const& whatToDoInCaseOfError )
{
// ...
throw whatToDoInCaseOfError; // slices
}
It's not a frequence case, but if you want to support it, you'll need a
separate exception hierarchy of your own, with a virtual raise
function:
class MyExceptions
{
public:
virtual ~MyExceptions() {}
virtual void raise() const = 0;
};
template<typename ExceptionType>
class ConcreteException : public ExceptionType, public MyExceptions
{
public:
virtual void raise() const
{
throw *this;
}
};
The client code then wraps the exception he wants to be thrown in a
ConcreteException, and you call the raise function on it, rather
than invoke throw directly.

Related

When exception class in c++ initialized?

#include <iostream>
#include <exception>
using namespace std;
struct MyException : public exception {
const char * what () const throw () {
return "C++ Exception";
}
};
int main() {
try {
throw MyException();
} catch(MyException& e) {
std::cout << "MyException caught" << std::endl;
std::cout << e.what() << std::endl;
} catch(std::exception& e) {
//Other errors
}
}
In above program, initializing MyException class is done in catch function parameter as catch(MyException& e) and initialization can also be done without & symbol.
My doubt is object of MyException class really created when & is used? What is the trick here?
the initialization happens here:
throw MyException();
because there you are creating a new instance of the class MyException...
anonymous instance (the object is not assigned to any variable declared by you) but there is the point where the constructor of your class is invoked and in consequence the initialization.
There's nothing special about exception classes. They're simply classes. Yes, they are intended to be used to communicate exception information, but any type can be used for that. So don't get hung up on the exception code itself; it has nothing to do with when the object is created. return MyException(); would create an object of type MyException. So does throw MyException();.

Call member's constructor in a Class constructor's try-catch block? [duplicate]

Here's a curious one. I have a class A. It has an item of class B, which I want to initialize in the constructor of A using an initializer list, like so:
class A {
public:
A(const B& b): mB(b) { };
private:
B mB;
};
Is there a way to catch exceptions that might be thrown by mB's copy-constructor while still using the initializer list method? Or would I have to initialize mB within the constructor's braces in order to have a try/catch?
Have a read of http://weseetips.wordpress.com/tag/exception-from-constructor-initializer-list/)
Edit: After more digging, these are called "Function try blocks".
I confess I didn't know this either until I went looking. You learn something every day! I don't know if this is an indictment of how little I get to use C++ these days, my lack of C++ knowledge, or the often Byzantine features that litter the language. Ah well - I still like it :)
To ensure people don't have to jump to another site, the syntax of a function try block for constructors turns out to be:
C::C()
try : init1(), ..., initn()
{
// Constructor
}
catch(...)
{
// Handle exception
}
It's not particularly pretty:
A::A(const B& b) try : mB(b)
{
// constructor stuff
}
catch (/* exception type */)
{
// handle the exception
}
I know it has been awhile since this discussion started. But that try-and-catch construct mentioned by Adam is part of the C++ standard and is supported by Microsoft VC++ and GNU C++.
Here is the program that works. By the way the the catch generates automatically another exception to signal about the constructor failure.
#include <iostream>
#include <exception>
#include <string>
using namespace std;
class my_exception: public exception
{
string message;
public:
my_exception(const char* message1)
{
message = message1;
}
virtual const char* what() const throw()
{
cout << message << endl;
return message.c_str();
}
virtual ~my_exception() throw() {};
};
class E
{
public:
E(const char* message) { throw my_exception(message);}
};
class A
{
E p;
public:
A()
try :p("E failure")
{
cout << "A constructor" << endl;
}
catch (const exception& ex)
{
cout << "Inside A. Constructor failure: " << ex.what() << endl;
}
};
int main()
{
try
{
A z;
}
catch (const exception& ex)
{
cout << "In main. Constructor failure: " << ex.what() << endl;
}
return 0;
}
You could work with lazy initialization, though, that is hold a unique_ptr to Reader in MyClass and create it with new. That way, you do not even need the flag has_reader but you can just see if your unique_ptr is initial or not.
#include <iostream>
#include <memory>
using namespace std;
class MyOtherClass
{
public:
MyOtherClass()
{
throw std::runtime_error("not working");
}
};
class MyClass
{
public:
typedef std::unique_ptr<MyOtherClass> MyOtherClassPtr;
MyClass()
{
try
{
other = std::make_unique<MyOtherClass>();
}
catch(...)
{
cout << "initialization failed." << endl;
}
cout << "other is initialized: " << (other ? "yes" : "no");
}
private:
std::unique_ptr<MyOtherClass> other;
};
int main()
{
MyClass c;
return 0;
}
Of course, there are also solutions without using exceptions at all but I assumed that this is a prerequisite in your setting.
I don't see how you'd do that with initializer-list syntax, but I'm also a bit sceptical that you'll be able to do anything useful by catching the exception in your constructor. It depends on the design of the classes, obviously, but in what case are you going to fail to create "mB", and still have a useful "A" object?
You might as well let the exception percolate up, and handle it wherever the constructor for A is being called.

Does rule of not embedding std::string in exceptions still hold with move constructors?

I heard some time ago that I should not create exception classes which would have fields of std::string type. That's what Boost website says. The rationale is that std::string copy constructor can throw an exception if memory allocation fails, and if an exception is thrown before the currently processed exception is caught, the program is terminated.
However, does it still hold in the world of move constructors? Won't the move constructor be used instead of the copy constructor when throwing an exception? Do I understand correctly that with C++11 no memory allocation will take place, no chance of exception exists and std::string is absolutely fine in exception classes now?
The answer is:
Yes, you still don't want to embed a std::string into your exception types. Exceptions are often copied, sometimes without your knowledge. For example, on some platforms std::rethrow_exception will copy the exception (and on some it won't).
For best practice, keep your copy constructor noexcept.
However all is not lost. A little known fact is that C++ has always had within the standard an immutable ref-counted string type (with a non-throwing copy constructor), just with an obfuscated name. Two names actually:
logic_error
runtime_error
The specs for these types are such that they must contain an immutable ref-counted string-like object. Well, not completely immutable. You can replace the string with an assignment. But you can't otherwise modify the string in place.
My advice is to either derive from one of these types, or if that is not acceptable, embed one of these types and treat it as an immutable ref-counted string type:
#include <stdexcept>
#include <iostream>
class error1
: public std::runtime_error
{
using msg_ = std::runtime_error;
public:
explicit error1(std::string const& msg)
: msg_(msg)
{}
};
class error2
{
std::runtime_error msg_;
public:
explicit error2(std::string const& msg)
: msg_(msg)
{}
char const* what() const noexcept {return msg_.what();}
};
void
test_error1()
{
try
{
throw error1("test1");
}
catch (error1 const& e)
{
std::cout << e.what() << '\n';
}
}
void
test_error2()
{
try
{
throw error2("test2");
}
catch (error2 const& e)
{
std::cout << e.what() << '\n';
}
}
int
main()
{
test_error1();
test_error2();
}
The std::lib will take care of all the string-handling and memory management for you, and you get noexcept copying in the bargain:
static_assert(std::is_nothrow_copy_constructible<error1>{}, "");
static_assert(std::is_nothrow_copy_assignable <error1>{}, "");
static_assert(std::is_nothrow_copy_constructible<error2>{}, "");
static_assert(std::is_nothrow_copy_assignable <error2>{}, "");
Whether a copy of the string is made when an exception is thrown depends on the catch block.
Take this example:
#include <iostream>
struct A
{
};
void foo()
{
throw A();
}
void test1()
{
try
{
foo();
}
catch (A&& a)
{
}
}
void test2()
{
try
{
foo();
}
catch (A const& a)
{
}
}
void test3()
{
try
{
foo();
}
catch (A a)
{
}
}
int main()
{
test1();
test2();
test3();
}
You will not make a copy of A in test1 or test2 but you will end up making a copy in test3.

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.