Try blocks and not catching exceptions

Discussion in 'C++' started by Adam H. Peterson, Jan 27, 2004.

  1. 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?
     
    Adam H. Peterson, Jan 27, 2004
    #1
    1. Advertising

  2. Adam H. Peterson

    Ron Natalie Guest

    "Adam H. Peterson" <> wrote in message news:bv5f73$9i3q$...

    > 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.
     
    Ron Natalie, Jan 27, 2004
    #2
    1. Advertising

  3. Adam H. Peterson

    lilburne Guest

    Adam H. Peterson wrote:
    > 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?
     
    lilburne, Jan 27, 2004
    #3
  4. Adam H. Peterson

    tom_usenet Guest

    On Tue, 27 Jan 2004 03:39:59 -0700, "Adam H. Peterson"
    <> wrote:

    >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
     
    tom_usenet, Jan 27, 2004
    #4
  5. Adam H. Peterson

    Ron Natalie Guest

    "tom_usenet" <> wrote in message news:...
    > >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....");
    > >}
    > >


    > 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();
     
    Ron Natalie, Jan 27, 2004
    #5
  6. On Tue, 27 Jan 2004 03:39:59 -0700, Adam H. Peterson wrote:

    > 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
     
    Martijn Lievaart, Jan 27, 2004
    #6
  7. Adam H. Peterson

    Jeff Schwab Guest

    Martijn Lievaart wrote:
    > On Tue, 27 Jan 2004 03:39:59 -0700, Adam H. Peterson wrote:
    >
    >
    >>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);


    /* ITYM */ 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);


    /* ITYM */ 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
    >
     
    Jeff Schwab, Jan 27, 2004
    #7
  8. On Tue, 27 Jan 2004 08:04:11 -0500, Jeff Schwab wrote:

    >
    > /* ITYM */ Derived *p=dynamic_cast<Derived*>(b);
    >
    >
    > /* ITYM */ Derived *p=dynamic_cast<Derived*>(b);
    >


    Auch. Yes.

    M4
     
    Martijn Lievaart, Jan 27, 2004
    #8
  9. Ron Natalie wrote:
    > "Adam H. Peterson" <> wrote in message news:bv5f73$9i3q$...
    >
    >> 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...");


    'if (!dp) ...' ?

    > dp->do_something_complicated();
    >
    > Actually looks like less code to me. Exceptions suck for errors that are
    > easily tested for by other means.


    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Jan 27, 2004
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul Sijben
    Replies:
    5
    Views:
    389
    Gabriel Genellina
    Mar 8, 2007
  2. Replies:
    4
    Views:
    300
  3. =?Utf-8?B?QUo=?=

    When to TRY and not to TRY

    =?Utf-8?B?QUo=?=, Oct 16, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    346
    sloan
    Oct 17, 2007
  4. matt
    Replies:
    1
    Views:
    296
    George Ogata
    Aug 6, 2004
  5. Steven Taylor
    Replies:
    9
    Views:
    280
    Brian Candler
    Apr 27, 2009
Loading...

Share This Page