FAQ 26.12 Under what circumstances can an overridden virtual member function throw exceptions other than those listed by the specification of the member function in the base class?

graphics/new_icon.gif

When the exception is an object of a class that is publicly derived from one of the classes mentioned in the exception specification of the base class's member function. This ensures that users of the base class won't be surprised.

Suppose class Base has member function f() that promises to throw only objects of class X. If class Derived overrides f() and throws an object of unrelated class Y, user code will break, because users will get an unexpected exception. However, Derived::f() can throw an X2 if X2 is derived from X due to the is-a conversion that allows a derived class reference to automatically be converted to a base class reference.

 #include <cstdlib> #include <iostream> using namespace std; class X { }; class Y { }; class X2 : public X { }; class Base { public:   virtual void f() throw(X);     //PROMISE: may throw 'X', but never throws anything else   virtual ~Base() throw(); }; Base::~Base() throw() { } void userCode(Base& base) throw() {   try {     base.f();     cout << "OK: base.f() didn't throw anything\n";   }   catch (X& x) {     cout << "OK: base.f() threw an X\n";   }   catch (...) {     cout << "huh? base.f() threw something other than X!\n";   } } class Derived : public Base { public:   virtual void f() throw(X, X2, Y);     //PROMISE:     //  may throw X                                  <-- 1     //  may throw X2                                 <-- 2     //  may throw Y                                  <-- 3 }; void Base::f() throw(X) { if (rand() % 2 == 0) throw X(); } void Derived::f() throw(X, X2, Y) {   int r = rand() % 4;   if (r == 0) throw X();                             <-- 4   if (r == 1) throw X2();                            <-- 5   if (r == 2) throw Y();                             <-- 6 } int main() {   Base    b;   Derived d;   cout << "using 'Base'\n";   for (int i = 0; i < 10; ++i)     userCode(b);   cout << "using 'Derived'\n";   for (int j = 0; j < 10; ++j)     userCode(d); } 

(1) OK: Users are expecting this

(2) OK: X2 is derived from X

(3) Bad form: Violates the promise of Base

(4) OK: Base users are expecting X

(5) OK: Base users are expecting X

(6) Bad: Base users don't expect Y

The overridden member function in the derived class has a weaker promise than that made by the base class: Base promised not to throw a Y, and Derived broke this promise.

Weakening a promise breaks user code.



C++ FAQs
C Programming FAQs: Frequently Asked Questions
ISBN: 0201845199
EAN: 2147483647
Year: 2005
Pages: 566
Authors: Steve Summit

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net