来自std :: exception的C ++异常和继承

时间:2010-04-03 00:02:57

标签: c++ exception inheritance private private-inheritance

鉴于此示例代码:

#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

然而,仅仅从my_exception_t std::exception继承public,我得到以下输出:

Exception: Hello, world!

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

2 个答案:

答案 0 :(得分:20)

当您私下继承时,您无法转换为或以其他方式访问该类之外的基类。因为你要求标准的东西:

  

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

简单地说,对于课外的任何事情,你都不会继承std::exception,因为它是私人的。因此,它不会被std::exception&子句捕获,因为不存在转换。

答案 1 :(得分: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. catch块具有匹配类型,或
  2. catch块适用于具有可访问转化
  3. 的类型
  4. catch块是一个catch(...)