为什么隐式转换在异常处理中从派生到基?

Why implicit conversion works from derived to base in exception handling?

本文关键字:派生 异常处理 转换 为什么      更新时间:2023-10-16

我了解到隐式转换不会在异常处理中执行,例如从floatintcharint等。但是当我在采访中被问到多态类时,当我应用同样的逻辑时,他们说这是错误的。所以这是我试图交叉检查的片段,它确实是错误的。

#include<iostream>
using namespace std;
class base
{
public:
virtual void what()
{
cout<<"caught in base"<<endl;
}
};
class derived : public base
{
public:
void what()
{
cout<<"caught in derived"<<endl;
}
};
void f()
{
throw derived(); // throwing instance of derived
}
void fprim()
{
throw 10.20f; // throwing float
}
int main()
{
try
{
f();
}
catch(base b)
{
cout<<"in base catch"<<endl;
b.what();
}
catch(derived d) // supposed to caught here
{
cout<<"in derived catch"<<endl; 
d.what();
}

// worked perfectly fir primitive 
try
{
fprim();
}
catch(int i)
{
cout<<"in int catch"<<endl;
}
catch(float f) 
{
cout<<"in float catch"<<endl;
}
return 0;
}

输出

in base catch
caught in base
in float catch
Press <RETURN> to close this window...

我期望输出中的第一行应该形成派生的 catch 语句。

那么有人可以告诉我为什么以及如何在这里进行隐式转换吗?

特别指出,允许基类的处理程序处理派生类的异常。

引自 [except.handle]/3:

处理程序是类型 E 的异常对象的匹配项,如果

处理程序的类型为 cv T 或 cv T
  • & 并且 E 和 T 是同一类型(忽略顶级 cv 限定符),或者

  • 处理程序的类型为 cv T 或
  • cv T& 和 T 是 E 的明确公共基类,或

  • 处理程序的类型为 cv T 或 const T&,其中 T 是指针或指向成员的类型,E 是指针或指向成员的类型,可以通过一个或多个转换为 T

    • 标准指针转换,不涉及转换为指向私有类、受保护类或不明确类的指针

    • 函数指针转换

    • 资格转换,或

  • 处理程序的类型为 cv T 或 const T& 其中 T 是指向成员的指针或指针类型,E 是 std::nullptr_t。