[comp.std.c++] Question about exception handling

mnm@hpclove.HP.COM (Michey Mehta) (10/31/90)

Hi,

This is a request for clarification about the exception handling
chapter in the ARM.

Consider the following example:

//////////////////////////////////////////////
class base {
public:
   virtual void fixit(){};
};

class derived : base {
public:
   virtual void fixit(){};
};

void func() {
   base* object = new derived;
   throw(*object);
}

main(){
   try {
      func();
   }
   catch(derived obj){
      obj.fixit();
   }
   catch(base obj){
      obj.fixit();
   }
}
//////////////////////////////////////////////

The question is: should derived::fixit be invoked or base::fixit?
The ARM says on page 356 "A throw-expression initializes a temporary
object of the static type of the operand of throw and uses that temporary
to initialize the appropriately-typed variable in the handler". 

1.  Since the ARM says *static type*, can we cut the object back to
being a "base" object?  

2. In that case, should we fall into the "catch (base obj)" ?

3. If so, isn't the vtbl entry for obj still pointing to derived::fixit,
   which could lead to problems?

Michey Mehta
Hewlett-Packard California Language Lab.     Internet: mnm@hpda.hp.com
Phone : (408) 447-5740                           UUCP: ...!hplabs!hpda!mnm

mnm@hpclove.HP.COM (Michey Mehta) (10/31/90)

Hi,

Looking at the ARM again, I realize that what it says is clear.
A sequence such as:

   base* object = new derived;
   throw(*object);

Should behave like this:

   base* object = new derived;
   base tmp_object = *object; //will invoke copy constructor for base
   throw(tmp_object);

This throw will be caught by a catch(base).  If the user wants to use
polymorphism, then a pointer should be thrown and the catch clause
should be "catch(base*)".

Michey Mehta
Hewlett-Packard California Language Lab.     Internet: mnm@hpda.hp.com
Phone : (408) 447-5740                           UUCP: ...!hplabs!hpda!mnm