C++ 异常处理和强制
为什么异常处理可以很好地处理子类型,但不能处理强制?C++11标准第15.3/3段定义了处理程序与特定异常对象匹配的确切条件,这些条件不允许用户定义的转换: 处理程序是类型为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),不涉及到私有或受保护指针的转换
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&
}