Try blocks and not catching exceptions

A

Adam H. Peterson

Hello,

I sometimes find myself writing code something like this:

try {
Derived &d=dynamic_cast<Derived&>(b);
d.do_something_complicated();
// etc....
} catch (std::bad_cast) {
throw Base_error("An object of incorrect type was given....");
}

The catch block is to do error translation if the user provided an
incorrect type, and I detect this in the dynamic_cast<>.

On the other hand, if a bad_cast exception is thrown in
do_something_complicated(), I don't want my catch block to catch that.
The catch block is only for catching and translating an error if it
occurs at _this_ dynamic_cast. However, I can't simply move
do_something_complicated() out of the try block, as that will be outside
d's scope.

I could probably get around this by turning d into a pointer and having
its declaration be outside the block, but then I end up with pointer
syntax and generally more verbose code. Also, there are cases where I'm
catching an exception from a constructor or something, where it's either
impossible or unadvisable to split the declaration and the
initialization of a variable, so the declaration really has to be inside
the try block.

What is the best way to handle this type of situation, so that I can
catch the exception I'm looking for, but not other exceptions in the
same scope that happen to be of the same type?
 
R

Ron Natalie

Adam H. Peterson said:
I could probably get around this by turning d into a pointer and having
its declaration be outside the block, but then I end up with pointer
syntax and generally more verbose code.

I don't know why it's more verbose (unless you thing -> is a lot more verbose than
..).

Derived* dp = dynamic_cast<Derived*>(&b);
if(dp) throw Base_error("An object of the wrong type...");

dp->do_something_complicated();

Actually looks like less code to me. Exceptions suck for errors that are
easily tested for by other means.
 
L

lilburne

Adam said:
Hello,

I sometimes find myself writing code something like this:

try {
Derived &d=dynamic_cast<Derived&>(b);
d.do_something_complicated();
// etc....
} catch (std::bad_cast) {
throw Base_error("An object of incorrect type was given....");
}

The catch block is to do error translation if the user provided an
incorrect type, and I detect this in the dynamic_cast<>.

If you don't know already know that b is a Derived why are you
downcasting to a reference? If you don't cast to a reference you won't
get an exception.

QUERY: Is this sort of thing exceptional programming or what?
 
T

tom_usenet

Hello,

I sometimes find myself writing code something like this:

try {
Derived &d=dynamic_cast<Derived&>(b);
d.do_something_complicated();
// etc....
} catch (std::bad_cast) {
throw Base_error("An object of incorrect type was given....");
}

The catch block is to do error translation if the user provided an
incorrect type, and I detect this in the dynamic_cast<>.

On the other hand, if a bad_cast exception is thrown in
do_something_complicated(), I don't want my catch block to catch that.
The catch block is only for catching and translating an error if it
occurs at _this_ dynamic_cast. However, I can't simply move
do_something_complicated() out of the try block, as that will be outside
d's scope.
What is the best way to handle this type of situation, so that I can
catch the exception I'm looking for, but not other exceptions in the
same scope that happen to be of the same type?

Derived& d = f(b);
d.do_something_complicated();

Where f has the try/catch block. You could create a generic version of
f:

template <class Derived, class Base, class ErrorHandler>
Derived& checked_dynamic_cast(Base& b, ErrorHandler eh)
{
try
{
return dynamic_cast<Derived&>(b);
}
catch(std::bad_cast const&)
{
return eh(); //may throw, return a default, or whatever
}
}

Derived& d = checked_dynamic_cast<Derived&>(b, base_error_thrower());
or similar.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 
R

Ron Natalie

Derived& d = f(b);
d.do_something_complicated();

Where f has the try/catch block. You could create a generic version of
f:
try { dynamic_cast<Derived&>(b); } castch (std::basd_cast) { throw Base_error("..."); } // probe for mines
Derived& d = dynamic_cast<Derived&>(b);
d.do_something_complicated();
 
M

Martijn Lievaart

Hello,

I sometimes find myself writing code something like this:

try {
Derived &d=dynamic_cast<Derived&>(b);
d.do_something_complicated();
// etc....
} catch (std::bad_cast) {
throw Base_error("An object of incorrect type was given....");
}

The catch block is to do error translation if the user provided an
incorrect type, and I detect this in the dynamic_cast<>.

On the other hand, if a bad_cast exception is thrown in
do_something_complicated(), I don't want my catch block to catch that.
The catch block is only for catching and translating an error if it
occurs at _this_ dynamic_cast. However, I can't simply move
do_something_complicated() out of the try block, as that will be outside
d's scope.

I could probably get around this by turning d into a pointer and having
its declaration be outside the block, but then I end up with pointer
syntax and generally more verbose code. Also, there are cases where I'm
catching an exception from a constructor or something, where it's either
impossible or unadvisable to split the declaration and the
initialization of a variable, so the declaration really has to be inside
the try block.

Read Rons excelent answer first. Now still want to do this?

Derived *p=dynamic_cast<Derived&>(b);
if (!p)
throw Base_error("An object of incorrect type was given....");
Derived &d=*p;
d.do_something_complicated();
// etc....

Or follow Toms advice and wrap this in a function:

Derived &down_cast(Base &b)
{
Derived *p=dynamic_cast<Derived&>(b);
if (!p)
throw Base_error("An object of incorrect type was given....");
return *p;
}

Derived &d=down_cast(b);
d.do_something_complicated();

HTH,
M4
 
A

Andrey Tarasevich

Ron said:
I don't know why it's more verbose (unless you thing -> is a lot more verbose than
.).

Derived* dp = dynamic_cast<Derived*>(&b);
if(dp) throw Base_error("An object of the wrong type...");

'if (!dp) ...' ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top