By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,852 Members | 2,219 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,852 IT Pros & Developers. It's quick & easy.

Exceptions and inheritance

P: n/a
I am a bit confused about how inheritance works with regard to
exceptions apparently.

class ParentEx : public std::exception
{
};

class SubEx : public ParentEx,std::runtime_error
{
};

SubEx is getting caught by catching ParentEx or SubEx, but not
std::exception.

Why?

Thanks.

Jul 23 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
Noah Roberts wrote:
I am a bit confused about how inheritance works with regard to
exceptions apparently.

class ParentEx : public std::exception
{
};

class SubEx : public ParentEx,std::runtime_error
{
};

SubEx is getting caught by catching ParentEx or SubEx, but not
std::exception.

Why?


Because std::exception is an ambiguous base. There are two of them.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
Jul 23 '05 #2

P: n/a

Pete Becker wrote:
Because std::exception is an ambiguous base. There are two of them.


Is there two in the headers or because I am using multiple inheritance
and both parents derive from that class?

Jul 23 '05 #3

P: n/a

Noah Roberts wrote:
Pete Becker wrote:
Because std::exception is an ambiguous base. There are two of them.
Is there two in the headers or because I am using multiple

inheritance and both parents derive from that class?

It is because of the multiple inheritance.

Hope this helps,
-shez-

Jul 23 '05 #4

P: n/a
Shezan Baig wrote:
Noah Roberts wrote: It is because of the multiple inheritance.

Figured. I still never quite get MI. Sometimes I really wish C++ did
the interface or protocol thing.

How would I set this kind of situation up then? I want all of these
exceptions to be considered as ParentExceptions, which needs to look
like an exception, but I also want to qualify some of them to say, "Well
this is a range_error, this is an xxx_error...That way the catch can be
either specific to the class, or more general in terms of stdlib.

Can that even be done or do I need to stop being silly?
Jul 23 '05 #5

P: n/a

"Noah Roberts" <nr******@dontemailme.com> wrote in message
news:11*************@corp.supernews.com...
Shezan Baig wrote:
Noah Roberts wrote:

It is because of the multiple inheritance.

Figured. I still never quite get MI. Sometimes I really wish C++ did
the interface or protocol thing.

How would I set this kind of situation up then? I want all of these
exceptions to be considered as ParentExceptions, which needs to look
like an exception, but I also want to qualify some of them to say, "Well
this is a range_error, this is an xxx_error...That way the catch can be
either specific to the class, or more general in terms of stdlib.

Can that even be done or do I need to stop being silly?


Well, why are you deriving ParentEx from std::exception in the first place?
Presumably you have some message passing mechanics implemented (or at least
specified) in ParentEx that you want to be common to all of your SubEx
classes, so it makes sense to have it as a base class, but does it have to
be derived from std::exception? Consider:

class ParentEx {};

class DefaultEx : public ParentEx, public std::exception {};
class SubEx : public ParentEx, public std::runtime_error {};

Now you can throw DefaultEx when you don't need anything special, and all of
your objects will have exactly one std::exception base object in the
hierarchy.

However, I am not sure what you are trying to do here? Typically I either
derive from my own exception classes, or from the std ones, but I have never
found the need to do both. It seems to me that it might cause ambiguities
when trying to handle the exceptions further down the line.

HTH,

Dave Moore
Jul 23 '05 #6

P: n/a

Dave Moore wrote:
Well, why are you deriving ParentEx from std::exception in the first

place?

Pretty much just to be sure that any subclass can be caught as
std::exception instead of having to rely on catch (...).

It could be a problem of me trying to be too general case...

Jul 23 '05 #7

P: n/a

Dave Moore wrote:
but does it have to
be derived from std::exception? Consider:

class ParentEx {};

class DefaultEx : public ParentEx, public std::exception {};
class SubEx : public ParentEx, public std::runtime_error {};


Ok, what kind of bogus crap would happen if ParentEx looked like this:

class ParentEx {
public:
virtual const char* what() const throw() {}
};

Jul 23 '05 #8

P: n/a

Dave Moore wrote:
class ParentEx {};

class DefaultEx : public ParentEx, public std::exception {};
class SubEx : public ParentEx, public std::runtime_error {};


Ok, I didn't realize public had to be said both times. I thought
public qualified all base classes after. The problem is fixed now, it
passes all tests.

Jul 23 '05 #9

P: n/a

"Noah Roberts" <nr******@stmartin.edu> wrote in message
news:11**********************@o13g2000cwo.googlegr oups.com...

Dave Moore wrote:
but does it have to
be derived from std::exception? Consider:

class ParentEx {};

class DefaultEx : public ParentEx, public std::exception {};
class SubEx : public ParentEx, public std::runtime_error {};


Ok, what kind of bogus crap would happen if ParentEx looked like this:

class ParentEx {
public:
virtual const char* what() const throw() {}
};


Hmm .. I am not completely sure (I also am not so familiar with MI), but I
think it would be ok, provided that you declare (and define) a what()
function in all derived classes (DefaultEx, SubEx). Otherwise the compiler
will (should) give an ambiguity error, because it cannot decide between
std::exception::what and ParentEx::what.

So again I ask, are you sure you need to use multiple inheritance here?

HTH,

Dave Moore
Jul 23 '05 #10

P: n/a

Dave Moore wrote:
class ParentEx {};

class DefaultEx : public ParentEx, public std::exception {};
class SubEx : public ParentEx, public std::runtime_error {};


Ok, I did that. It still isn't working:

try
{
Date date("INVALID"); // Throws InvalidDateStringEx
fail_("Not thrown");
}
catch (std::exception e)
{
succeed_();
}
catch (...)
{
fail_("Not a std::exception.");
}

result of test run:
8DateTest failure: (Not a std::exception.) , DateTest.cpp (line 141)
Test "8DateTest":
Passed: 42 Failed: 1

The exceptions look like:

class DateException
{
// Derived classes should also inherit from std::exception.
};
class InvalidDateStringException : public
Date::DateException,std::runtime_error // string parse error.
{
public:
InvalidDateStringException(const std::string& msg = "") :
std::runtime_error(msg) {}
};

All other exception tests work, it registers as itself and
Date::DateException but not std::exception.

Jul 23 '05 #11

P: n/a
Noah Roberts wrote:

[ ... ]
Figured. I still never quite get MI. Sometimes I really wish C++
did the interface or protocol thing.
MI is simply a generalized form -- it lets you do interfaces and
protocols, and a number of other things as well when needed.
How would I set this kind of situation up then? I want all of these
exceptions to be considered as ParentExceptions, which needs to look
like an exception, but I also want to qualify some of them to say,
"Well this is a range_error, this is an xxx_error...That way the
catch can be either specific to the class, or more general in terms
of stdlib.


At least at first blush, this sounds like you want std::exception as
the ultimate base class. You'll then derive your ParentException from
that, and the others from there.

I'm not entirely sure I've correctly interpreted what you've said
though.

Exceptions are _rarely_ a good time to use MI -- exceptions generally
seem to work best as a big more or less monolithic hierarchy.

I can concieve of one possibility though: assume you have a big program
in an existing framework (e.g. MFC) that already has its own exception
handling, its own exception hierarchy, etc. You want to migrate to the
std::exception hierarchy without doing wholesale modifications on your
large body of working code. At the same time, you need to be able to
throw an exception that can be caught by an existing handler that
expects something derived from CExecption, or by a new handler that
expects something derived from std::exception.

In this case, it might be reasonable to build a shadow hierarchy (so to
speek) that unifies the two. An example might be something like:

class you::range_error : public std::range_error, public
CRangeException {
// ...
};

and if your code throws one of these, it can be caught and viewed as
either an std::range_error, OR a CRangeException, whichever sort of
handler is found first.

This, however, looks to be like it has the potential for getting ugly
pretty quickly, and I hasten to point out that I'm _not_ particularly
recommending it as a good technique -- just pointing out a situation
where I can imagine that multiple inheritance and exceptions _might_
mix in a way that isn't immediately problematic.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 23 '05 #12

P: n/a
Noah Roberts wrote:

[ ... ]
Figured. I still never quite get MI. Sometimes I really wish C++
did the interface or protocol thing.
MI is simply a generalized form -- it lets you do interfaces and
protocols, and a number of other things as well when needed.
How would I set this kind of situation up then? I want all of these
exceptions to be considered as ParentExceptions, which needs to look
like an exception, but I also want to qualify some of them to say,
"Well this is a range_error, this is an xxx_error...That way the
catch can be either specific to the class, or more general in terms
of stdlib.


At least at first blush, this sounds like you want std::exception as
the ultimate base class. You'll then derive your ParentException from
that, and the others from there.

I'm not entirely sure I've correctly interpreted what you've said
though.

Exceptions are _rarely_ a good time to use MI -- exceptions generally
seem to work best as a big more or less monolithic hierarchy.

I can concieve of one possibility though: assume you have a big program
in an existing framework (e.g. MFC) that already has its own exception
handling, its own exception hierarchy, etc. You want to migrate to the
std::exception hierarchy without doing wholesale modifications on your
large body of working code. At the same time, you need to be able to
throw an exception that can be caught by an existing handler that
expects something derived from CExecption, or by a new handler that
expects something derived from std::exception.

In this case, it might be reasonable to build a shadow hierarchy (so to
speek) that unifies the two. An example might be something like:

class you::range_error : public std::range_error, public
CRangeException {
// ...
};

and if your code throws one of these, it can be caught and viewed as
either an std::range_error, OR a CRangeException, whichever sort of
handler is found first.

This, however, looks to be like it has the potential for getting ugly
pretty quickly, and I hasten to point out that I'm _not_ particularly
recommending it as a good technique -- just pointing out a situation
where I can imagine that multiple inheritance and exceptions _might_
mix in a way that isn't immediately problematic.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Jul 23 '05 #13

P: n/a
Noah Roberts wrote:
Pete Becker wrote:

Because std::exception is an ambiguous base. There are two of them.

Is there two in the headers or because I am using multiple inheritance
and both parents derive from that class?


The latter. When you try to catch std::exception&, the compiler doesn't
know if you want to catch ParentEx's std::exception base or SubEx's
std::runtime_error base.
Jul 23 '05 #14

P: n/a

"Noah Roberts" <nr******@stmartin.edu> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...

[snip]
class InvalidDateStringException : public
Date::DateException,std::runtime_error // string parse error.
{
public:
InvalidDateStringException(const std::string& msg = "") :
std::runtime_error(msg) {}
};

All other exception tests work, it registers as itself and
Date::DateException but not std::exception.

looks like you forgot to specify "public" again in the specifications of the
base classes for InvalidDateStringException .. or is that just a posting
transcription error?

Dave Moore
Jul 23 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.