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块中调用,那么它调用正确的虚方法,否则它不... ..任何人都可以告诉我控制流程....请指教....
因为在抛出之前复制了一个对象.
即使参数a
的foo
点的实例B
在运行时,重要的是在编译时抛出表达的类型.因此,实际上,实例B
被传递给A
(自B
继承以来是合法的A
)复制构造函数,并A
创建并抛出新实例.
复制的原因是编译器必须保证异常对象的生命周期,只要有任何catch
块可以捕获它.因此,它不会冒着堆栈对象"从堆栈边缘掉下来"的风险,或者堆栈对象在堆栈展开期间调用的某些析构函数被释放.