异常处理+多态,如果异常方法不起作用,则在同一个类中不起作用

how*_*rks 2 c++ polymorphism virtual-functions exception throw

我正在尝试这样的代码

//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;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果我使用案例1:抛出一个; // a是B b的引用; 输出:错误

案例2:抛出B(); //创建新的B; 输出:B错误

我不明白的是,为什么两个案例之间没有一致性,

如果你一直通过引用传递,应该有一些一致性,如果我在函数内部创建一个新的变量,在try块中调用,那么它调用正确的虚方法,否则它不... ..任何人都可以告诉我控制流程....请指教....

Bra*_*vic 5

因为在抛出之前复制了一个对象.

即使参数afoo点的实例B在运行时,重要的是在编译时抛出表达的类型.因此,实际上,实例B被传递给A(自B继承以来是合法的A)复制构造函数,并A创建并抛出新实例.

复制的原因是编译器必须保证异常对象的生命周期,只要有任何catch块可以捕获它.因此,它不会冒着堆栈对象"从堆栈边缘掉下来"的风险,或者堆栈对象在堆栈展开期间调用的某些析构函数被释放.