try
{
throw Derived();
}
catch (Base&)
{
std::cout << "subtyping\n";
}
try
{
throw "lol";
}
catch (std::string)
{
std::cout << "coercion\n";
}输出:
subtyping
terminate called after throwing an instance of 'char const*'为什么异常处理和子类型很好,而不是强制?
发布于 2013-02-27 04:41:58
捕获抛出的异常与向函数传递参数有很大的不同。有相似之处,但也有微妙的区别。
3个主要区别是:
all)
catch子句按照声明的顺序进行检查(catch子句按照声明的顺序进行检查)(不是best-fit)const void*捕获任何类型
不允许任何其他类型的转换(例如,int到double,或隐式const char*到string -您的示例)。
对于您在评论中提出的问题,假设存在一个层次结构:
class Base {};
class Derived: public Base {};
class Base2 {};
class Leaf: public Derived, public Base2 {};现在,根据catch子句的顺序,将执行适当的块。
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&
}如果您切换Base和Base2捕获顺序,您将注意到不同的行为。如果Leaf从Base2私有继承,那么无论放在哪里,catch Base2&都是不可访问的(假设我们抛出一个Leaf)
一般来说很简单:顺序很重要。
发布于 2013-02-27 04:21:21
C++11标准的15.3/3段定义了处理程序与某个异常对象匹配的确切条件,这些条件不允许用户定义的转换
如果满足以下条件,则
处理程序与
E类型的异常对象匹配
-处理程序的类型为cv T或cv T&,E和T的类型相同(忽略顶级cv-qualifiers),或者
-处理程序的类型为cv T或cv T&,并且T是E的明确公共基类,或者
-处理程序的类型为cv1 T* cv2,而E是一种指针类型,可通过以下两种方式之一或全部转换为处理程序的类型
-处理程序是一个指针或指向成员类型的指针,并且E为std::nullptr_t。
..。
https://stackoverflow.com/questions/15098345
复制相似问题