menu

hjk41的日志

Avatar

More Effective C++ 12: Understand how throwing an exception differs from passing a parameter or ...

Understand how throwing an exception differs form passing a parameter or calling a virtual function.

There are three major differences:
1. Exception objects are always copied. When caught by value, they are copied twice.


class Widget { ... };

catch (Widget w) ...  
    // two copies of the exception objects are made.
    // 1.  the throw object -> temporary object
    // 2.  temporary object -> w            
catch (Widget& w)   ...               
catch (const Widget& w) ...
    // one copy
    // the thrown object -> temporary object
    // Widget & w=temporary object         
catch (Widget *pw) ...               
catch (const Widget *pw) ...
    // pointers are copied
    // for Widget * pw, two copies
    // for const Widget * pw, one copy

2. catch(double d) won't catch an int. Exception objects can only be converted up the inheritance hierarchy.


try{
    ...
    int a;
    throw a 
}catch(double d){...}    // a won't be caught

class A;
class B:public A;
try{
    ...
    B b;
    throw b; 
}catch(A & a){...}  // okay, b can be caught

3. Exception objects are caught in first-fit order.


class A;
class B:public A;
try{
    ...
    B b;
    throw b; 
}
catch(A & a){...}  // this catches exceptions of type
                         // A and all its derived classes
catch(B & b){...}  // this will never be executed, for all B are caught by
                          // the one above

The difference between throw; and throw a;


class A;
class B:public A;
try{
    ...
    B exc_b;
    throw exc_b; 
}
catch(A & a){
    ...
    throw;    // this throws a copy of exc_b (the temporary object)
}

try{
    ...
    B exc_b;
    throw exc_b; 
}
catch(A & a){
    ...
    throw a;   // this performs A a=exc_b;(the temporary object) and then throw a
}

评论已关闭