Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |
Each public function in a class essentially forms a contract with the user; if you pass it certain arguments, it will perform
certain operations and/or return a result. The same contract must hold true in
derived classes; otherwise the expected is-a relationship between derived and
base classes is violated. Since exception specifications are logically part of
a function s declaration, they too must remain consistent across an inheritance
hierarchy. For example, if a member function in a base class says it will only
throw an exception of type A, an override of that function in a derived
class must not add any other exception types to the specification list because
that would break any programs that adhere to the base class interface. You can,
however, specify fewer exceptions or none at all, since that
doesn t require the user to do anything differently. You can also specify
anything that is-a A in place of A in the derived function s
specification. Here s an example.
//: C01:Covariance.cpp {-xo}
// Should cause compile error. {-mwcc}{-msc}
#include <iostream>
using namespace std;
class Base {
public:
class BaseException {};
class DerivedException : public BaseException {};
virtual void f() throw(DerivedException) {
throw DerivedException();
}
virtual void g() throw(BaseException) {
throw BaseException();
}
};
class Derived : public Base {
public:
void f() throw(BaseException) {
throw BaseException();
}
virtual void g() throw(DerivedException) {
throw DerivedException();
}
}; ///:~
A compiler should flag the override of Derived::f( )
with an error (or at least a warning) since it changes its exception
specification in a way that violates the specification of Base::f( ).
The specification for Derived::g( ) is acceptable because DerivedException
is-a BaseException (not the other way around). You can think of Base/Derived
and BaseException/DerivedException as parallel class hierarchies; when
you are in Derived, you can replace references to BaseException
in exception specifications and return values with DerivedException.
This behavior is called covariance (since both sets of classes vary down their respective hierarchies together). (Reminder from Volume 1: parameter types are not
covariant you are not allowed to change the signature of an overridden virtual
function.)
Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |