C++ 异常处理和强制

C++ 异常处理和强制,c++,exception-handling,language-design,coercion,subtyping,C++,Exception Handling,Language Design,Coercion,Subtyping,为什么异常处理可以很好地处理子类型,但不能处理强制?C++11标准第15.3/3段定义了处理程序与特定异常对象匹配的确切条件,这些条件不允许用户定义的转换: 处理程序是类型为Eif的异常对象的匹配项 -处理程序的类型为cv T或cv T&和E和T是同一类型(忽略顶级cv限定符), 或 -处理程序的类型为cvt或cvt&,T是E的明确公共基类,或 -处理程序的类型为cv1 T*cv2,而E是一种指针类型,可以转换为 由一方或双方处理 一种标准指针转换(4.10),不涉及到私有或受保护指针的转换

为什么异常处理可以很好地处理子类型,但不能处理强制?

C++11标准第15.3/3段定义了处理程序与特定异常对象匹配的确切条件,这些条件不允许用户定义的转换:

处理程序是类型为
E
if的异常对象的匹配项

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

-处理程序的类型为
cvt
cvt&
T
E
的明确公共基类,或

-处理程序的类型为
cv1 T*cv2
,而
E
是一种指针类型,可以转换为 由一方或双方处理

  • 一种标准指针转换(4.10),不涉及到私有或受保护指针的转换 或模棱两可的类

  • 资格转换

-处理程序是一个指针或指向成员类型的指针,
E
std::nullptr\u t

[……]


捕获抛出的异常与向函数传递参数有很大不同。 有相似之处,但也有细微的差异

三个主要区别是:

  • 异常总是至少复制一次(根本无法避免)
  • catch
    子句按照声明的顺序进行检查(不是最佳匹配)
  • 它们的类型转换形式较少
    • 基于继承的覆盖
    • 从类型化指针到非类型化指针的转换(
      const void*
      捕获任何指针)
不允许任何其他类型的转换(例如,
int
double
,或隐式
const char*
字符串
——您的示例)

关于评论中的问题 假设存在一个层次结构:

subtyping
terminate called after throwing an instance of 'char const*'
现在,根据
catch
子句的顺序,将执行适当的块

class Base {}; 
class Derived: public Base {};
class Base2 {};
class Leaf: public Derived, public Base2 {};
试试看{

无法在抛出异常以尝试匹配异常处理程序时创建新对象。因为
派生()
,可以由
基&
绑定,但
强制
不是一个
std::string
。catch子句捕获现有对象。如果第二个catch块的类型为
myOwnString
,会发生什么情况?这不是很模糊吗?@Pubby好吧,如果第二个catch块的基址不同呢?这个问题仍然没有接受的具体原因吗答案是什么?
class Base {}; 
class Derived: public Base {};
class Base2 {};
class Leaf: public Derived, public Base2 {};
try {
    cout << "Trying ..." << endl;
    throw Leaf();

} catch (Base& b) {
    cout << "In Base&";

} catch (Base2& m) {
    cout << "In Base2&"; //unreachable due to Base&

} catch (Derived& d) {
    cout << "In Derived&";  // unreachable due to Base& and Base2&
}