The C++ Standard states the following about virtual functions that have exception specifications:
If a virtual function has an exception-specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall only allow exceptions that are allowed by the exception-specification of the base class virtual function (C++03 §15.4/3).
Thus, the following is ill-formed:
struct B {
virtual void f() throw() { } // allows no exceptions
};
struct D : B {
virtual void f() { } // allows all exceptions
};
(1) Does this rule apply to destructors? That is, is the following well-formed?
struct B {
virtual ~B() throw() { }
};
struct D : B {
virtual ~D() { }
};
(2) How does this rule apply to an implicitly declared destructor? That is, is the following well-formed?
struct B {
virtual ~B() throw() { }
};
struct D : B {
// ~D() implicitly declared
};
While in the general case one should never write an exception specification, this question has practical implications because the std::exception
destructor is virtual and has an empty exception specification.
Since it is good practice not to allow an exception to be thrown from a destructor, let's assume for the sake of simplifying any examples that a destructor either allows all exceptions (that is, it has no exception specification) or it allows no exceptions (that is, it has an empty exception specification).