Re: Are so many subclasses such a good idea?
<khapi@yahoo.com> wrote in message
news:8b9779e5-5399-4da4-93df-2b6f338caf13@m3g2000hsc.googlegroups.com...
On Jun 12, 5:49 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
And where is the _selective_ catching of errors?
Here:
try {
if (a)
throw(UNHAPPY);
if (b)
throw(UNHAPPIER);
if (c)
throw(UNHAPPIEST);
} catch (int which) {
switch (which) {
case UNHAPPY: ... break;
case UNHAPPIER: ... break;
case UNHAPPIEST: ... break;
}
}
The point is: different exceptions can rise up in the call stack to
different levels. The type determines which catch handler is used.
True, that reinforces C++'s compile-time typing,
which some consider to be an advantage of C++.
Why use the switch statement when the nature of the try/catch functionality
can do this for you? Example:
namespace error {
struct base {};
namespace mood {
struct base : public error::base {};
struct unhappy : public mood::base {};
struct unhappier : public mood::base {};
struct unhappiest : public mood::base {};
}
}
try {
if (a) { throw error::mood::unhappy(); }
if (b) { throw error::mood::unhappier(); }
if (c) { throw error::mood::unhappiest(); }
} catch (error::mood::unhappiest const& e) {
} catch (error::mood::unhappier const& e) {
} catch (error::mood::unhappy const& e) {
} catch (error::mood::base const& e) {
} catch (error::base const& e) {
} catch (...) {
}
The C++ exception handling mechanism is very expressive. I personally like
it a lot. Here is another example. Take a mutex class which can throw
exceptions. Here is one way to write it:
___________________________________________________________________
class mutex_with_exceptions {
pthread_mutex_t m_mtx;
[...];
public:
struct error {
struct base {};
struct lock {
struct base : public error::base {};
struct invalid : public lock::base {};
struct priority_violation : pubilc lock::invalid {};
struct deadlock : public lock::base {};
struct max_recursion : public lock::base {};
static void raise_status(int const status) {
switch (status) {
case EINVAL:
throw priority_violation();
case EAGAIN:
throw max_recursion();
case EDEADLK:
throw deadlock();
default:
assert(false);
std::unexpected();
}
}
};
struct unlock {
struct base : public error::base {};
struct not_owner : public unlock::base {};
static void raise_status(int const status) {
switch (status) {
case EPERM:
throw not_owner();
default:
assert(false);
std::unexpected();
}
}
};
};
public:
void lock() {
int const status = pthread_mutex_lock(&m_mtx);
if (status) {
error::lock::raise_status(status);
}
}
void unlock() {
int const status = pthread_mutex_unlock(&m_mtx);
if (status) {
error::unlock::raise_status(status);
}
}
};
___________________________________________________________________
The exception hierarchy for the `mutex_with_exceptions' class is verbose.
Any thoughts?