我正在尝试这样的代码
//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;
}
在这种情况下,如果我使用 情况1: 扔一个;//a 是 B b 的引用; 输出:一个错误
案例二: 抛出 B();//创建新的 B; 输出:B 错误
我不明白的是,为什么两个案例之间没有一致性,
如果你一直按引用传递,应该有一些一致性, 如果我在函数内创建一个新变量,在 try block 中调用,那么它会调用正确的虚拟方法,否则它不会......任何人都可以告诉我控制流程......请告知。 ...
最佳答案
因为一个对象在抛出之前被复制了。
即使 foo
的参数 a
在运行时指向 B
的实例,重要的是 compile -time 抛出表达式的类型。因此,实际上,B
的实例被传递给了 A
的复制构造函数(这是合法的,因为 B
继承了 A
) 和一个新的 A
实例被创建然后抛出。
复制的原因是编译器必须保证异常对象的生命周期,只要有任何catch
block 可以捕获它。因此,它不能冒堆栈对象“从堆栈边缘掉落”或堆对象被堆栈展开期间调用的某些析构函数释放的风险。
关于c++ - 异常处理+多态,如果异常方法不起作用,在同一个类中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9405538/