首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异常处理和强制

异常处理和强制
EN

Stack Overflow用户
提问于 2013-02-27 04:12:16
回答 2查看 286关注 0票数 12
代码语言:javascript
复制
try
{
    throw Derived();
}
catch (Base&)
{
    std::cout << "subtyping\n";
}

try
{
    throw "lol";
}
catch (std::string)
{
    std::cout << "coercion\n";
}

输出:

代码语言:javascript
复制
subtyping
terminate called after throwing an instance of 'char const*'

为什么异常处理和子类型很好,而不是强制?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-27 04:41:58

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

3个主要区别是:

all)

  • catch子句按照声明的顺序进行检查(
  • 异常始终至少复制一次(不是all)
  • catch子句按照声明的顺序进行检查)(不是best-fit)
  • they会受到较少形式的类型转换的影响):
    • inheritance-based转换,从类型化指针到非类型化指针的
    • 转换(const void*捕获任何类型

不允许任何其他类型的转换(例如,intdouble,或隐式const char*string -您的示例)。

对于您在评论中提出的问题,假设存在一个层次结构:

代码语言:javascript
复制
class Base {}; 
class Derived: public Base {};
class Base2 {};
class Leaf: public Derived, public Base2 {};

现在,根据catch子句的顺序,将执行适当的块。

代码语言:javascript
复制
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&
}

如果您切换BaseBase2捕获顺序,您将注意到不同的行为。如果LeafBase2私有继承,那么无论放在哪里,catch Base2&都是不可访问的(假设我们抛出一个Leaf)

一般来说很简单:顺序很重要。

票数 18
EN

Stack Overflow用户

发布于 2013-02-27 04:21:21

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

如果满足以下条件,则

处理程序与E类型的异常对象匹配

-处理程序的类型为cv Tcv T&ET的类型相同(忽略顶级cv-qualifiers),或者

-处理程序的类型为cv Tcv T&,并且TE的明确公共基类,或者

-处理程序的类型为cv1 T* cv2,而E是一种指针类型,可通过以下两种方式之一或全部转换为处理程序的类型

  • a标准指针转换(4.10)不涉及到指向私有类、受保护类或不明确类的指针的转换
  • a qualification

-处理程序是一个指针或指向成员类型的指针,并且Estd::nullptr_t

..。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15098345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档