I have a class hierarchy, and each class in it has an exception class, derived in a parallel hierarchy, thus…
class Base
{
};
class Derived : public Base
{
};
class BaseException : public std::exception
{
enum {THIS_REASON, THAT_REASON};
};
class DerivedException : public BaseException
{
// er...what?
};
I would like, in the DerivedException class, to extend the enumeration type to include a new value THE_OTHER_REASON, so that the DerivedException class could hold any of the three values.
First of all, ought I to want to do this? Does it seem a reasonable practice? If so, how do I go about it? If not, what alternatives would you recommend?
EDIT: A possible duplicate has been suggested here, but the suggested solutions are different because that question is for C# and this for C++.
From the OO standpoint, it is not reasonable. Since you say that
DerivedExceptionis-aBaseException, its possible reasons must be a subset of that ofBaseException, not a superset. Otherwise you ultimately break the Liskov Substitution Principle.Moreover, since C++ enums are not classes, you can’t extend or inherit them. You can define additional reasons in a separate enum within
DerivedException, but then ultimately you bump into the same problem described above:What you can do instead is define a separate exception subclass for each distinct reason. Then you can handle them polymorphically (if needed). This is the approach of the standard C++ library as well as other class libraries. Thus you adhere to the conventions, which makes your code easier to understand.