Search code examples
c++exceptionpolymorphismvirtual-functionsthrow

Exception Handling + polymorphism, doesnt work if the exception method, doesnt work in the same class


I am trying some code like this

//A.hpp
 class A{
   public:
       A() {} 
       virtual const char *message() const {return "A ERROR";}
 };

 //B.hpp

 #include "A.hpp"

 class B:public A {
   public:
       B() {}
       const char *message() const {return "B ERROR";}
 };

//main.cpp
 #include "A.hpp"
 #include "B.hpp"

void foo(const A& a) {
   /* case 1 */ throw a;   /* (or) */ /* case 2 */ throw B(); // LINE 100
}

int main() {

  B b;
  A &a(b);
  b.message(); // OUTPUT: B ERROR

  try {
      foo(a);
  } catch (const A& a) {
     std::cout<<"EXCEPTION CALLED "<<a.message()<<std::endl;
  }
  return 0;
}

in this case, if I use case 1: throw a; //a is an reference of B b; OUTPUT: A ERROR

case 2: throw B(); // creates new B; OUTPUT: B ERROR

What I don't understand is, why doesn't there is no consistency betweek two cases,

If you pass by reference, all the time, there should be some consistency, If I create a new variable inside the function, that is called in the try block, then it calls the correct virtual method, else it doesn't..... Can anyone tell me the control flow.... Please advise....


Solution

  • Because an object is copied before thrown.

    Even if the parameter a of foo points to an instance of B at run-time, what matters is the compile-time type of the throw expression. So, effectively, the instance of B is passed to the copy-constructor of A (which is legitimate since B inherits A) and a new A instance created and then thrown.

    The reason for copy is that compiler must guarantee the lifetime of the exception object as long as there is any catch block that could catch it. So, it can't risk a stack object "falling off the stack edge" or heap object being deallocated by some destructor invoked during stack unwinding.