2010-04-03 88 views
10

鉴于此示例代码:C++异常和性病继承::异常

#include <iostream> 
#include <stdexcept> 

class my_exception_t : std::exception 
{ 
public: 
    explicit my_exception_t() 
    { } 

    virtual const char* what() const throw() 
    { return "Hello, world!"; } 
}; 

int main() 
{ 
    try 
     { throw my_exception_t(); } 
    catch (const std::exception& error) 
     { std::cerr << "Exception: " << error.what() << std::endl; } 
    catch (...) 
     { std::cerr << "Exception: unknown" << std::endl; } 

    return 0; 
} 

我得到以下输出:

Exception: unknown 

然而,简单地从std::exceptionpublic使得my_exception_t继承,我得到以下输出:

Exception: Hello, world! 

是否有人pl向我解释为什么继承类型在这种情况下很重要?奖励积分为标准中的参考。

回答

20

当你继承私下,你不能转换或以其他方式访问该基类的类型在课外。既然你问的东西,从标准:

§11.2/ 4:
基类被认为是可访问的,如果基类的发明公共成员进行访问。如果基类是可访问的,那么可以隐式地将指向派生类的指针转换为指向该基类的指针(4.10,4.11)。

简而言之,对于班级以外的任何事情来说,就像你永远不会从std::exception继承,因为它是私人的。因为不存在转换,因此它将无法在std::exception&子句中被捕获。

+0

接受标准参考;谢谢! – fbrereto 2010-04-03 03:44:54

9

请问有人可以向我解释为什么 继承的类型在 这个情况下很重要吗?标准中 参考的奖励积分。

继承的类型并不重要。只有你有一个可用的转换可用于其中一种捕获类型。它恰好如此,因为它不是公有继承,所以没有公共可访问的转换。


说明:

你可以看到相同的行为在这里:

class B 
{ 
}; 

class C1 : B 
{ 
}; 

class C2 : public B 
{ 
}; 

int main(int argc, char** argv) 
{ 
    B& b1 = C1();//Compiling error due to conversion exists but is inaccessible 
    B& b2 = C2();//OK 
    return 0; 
} 

抛出的异常仅由一个catch块捕获,如果:

  1. 渔获块具有匹配类型,或
  2. catch块是一个具有访问的变换
  3. catch块是一个catch(...)
+0

'my_exception_t'派生自两种情况下的'std :: exception'。 – fbrereto 2010-04-03 00:17:21

+0

@fbrereto:谢谢你的澄清,我在我的回答中解释过,请重新阅读。 – 2010-04-03 00:23:44