C++ 为什么基类catch子句可以捕获派生类异常。
我在Xcode上尝试了以下代码C++ 为什么基类catch子句可以捕获派生类异常。,c++,exception,C++,Exception,我在Xcode上尝试了以下代码 #include <iostream> /*Exceptions*/ struct A { A( int value ) : m_value( value ) {} int m_value; }; struct B : A { B( int value ) : A( value ) {} }; //+++++++++++++++++++++++++++++++ /*Exceptions End*/ int main(i
#include <iostream>
/*Exceptions*/
struct A {
A( int value ) : m_value( value ) {}
int m_value;
};
struct B : A {
B( int value ) : A( value ) {}
};
//+++++++++++++++++++++++++++++++
/*Exceptions End*/
int main(int argc, const char * argv[]) {
try {
try {
throw B( 5 );
}
catch ( A a ) {
a.m_value *= 2;
}
catch ( B b ) {
b.m_value -= 2;
throw b;
}
}
catch ( A a ) {
std::cout << a.m_value;
}
return 0;
}
执行catch(A)
时确实会输出hello,但当我显式定义复制构造函数时,如下所示:
explicit A( const A& other ) : m_value( other.m_value ) {
std::cout << "hello\n";
}
显式A(常数A和其他):m_值(其他m_值){
STD::CUT< P>因为Ccatch(a…)>代码>第一个。这是C++的一个错误特性。理想地,它会给您一个编译错误: catch /Cuth.Bug无序,或者至少对于不可达代码。放<代码> catch(b…)>代码>。 < P>
try块的处理程序是按外观顺序尝试的。这样就可以编写
不能执行,例如,方法是将派生类的处理程序放在对应类的处理程序之后
基类。
如果在启用警告的情况下编译,也会变得很清楚:
main.cpp:28:9: warning: exception of type 'B' will be caught
catch ( B b ) {
^
main.cpp:24:9: warning: by earlier handler for 'A'
catch ( A a ) {
^
是的,一旦抛出B
,我们就可以一个接一个地查看处理程序列表。我们可以通过A
捕获吗?是的,我们可以!AB
可以转换为A
现在,当您创建A
的复制构造函数时,会发生一些有趣的事情。您不能将B
隐式转换为A
,但异常逻辑处理并不是这样做的。它只是检查类型。根据:
处理程序是类型为E
if
-[…]
-处理程序的类型为cvT
或cvT&
,T
是E
或
-[……]
在我们的例子中,A
是B
的一个明确的公共基类,处理程序的类型是A
,因此处理程序匹配。句号。现在,事实证明我们不能实际使用处理程序,所以代码格式不正确。问题是,如果我将复制构造函数定义为显式,它将无法编译。您应该通过引用捕获NC:<代码> catch(a &…)<代码>,同样地,如果没有可能的话,没有理由用值来捕获异常。如果知道,这是一个采访问题。即使引用,它仍然通过值,因为unFungRelad,我的C++知识早于代码>显式< /代码>。非常简单!谢谢!
main.cpp:28:9: warning: exception of type 'B' will be caught
catch ( B b ) {
^
main.cpp:24:9: warning: by earlier handler for 'A'
catch ( A a ) {
^