【问题标题】:Class that is privately inherited from std::runtime_error is not caught as std::exception从 std::runtime_error 私有继承的类不会被捕获为 std::exception
【发布时间】:2014-12-17 07:53:00
【问题描述】:

这一切都在这个例子中

class MyException: std::runtime_error // note, there is no public keyword in inheritance
{
public:
   MyException(const std::string & x)
      : std::runtime_error(x)
   {}
};


int main( )
{
   try
   {
      throw MyException("foo");
   }
   catch (std::exception & e )
   {
      std::cout << "catched std exception: " << e.what() << std::endl;
   }
   catch (...)
   {
      std::cout << "catched ... " << std::endl;
   }
}

它写入标准输出字符串“catched ...”。但是,如果我将继承更改为class MyException : public std::runtime_error,它会按预期工作(对我而言)并写入“catched std exception: foo”

c++ 标准的哪一部分需要这种行为?为什么?在什么情况下这种行为可能有用?

【问题讨论】:

    标签: c++ exception try-catch


    【解决方案1】:

    这是有道理的,并且与重载解决的规则一致。在MyException 之外,您的班级不是 std::exception。您应该将私有继承视为一个实现细节(具有很高的耦合度。)

    在15.3 处理异常:

    如果

    ,则处理程序是 E 类型的异常对象的匹配项

    - 处理程序的类型为 cv T 或 cv T& 并且 E 和 T 是同一类型 (忽略顶级 cv 限定符),或

    — 处理程序的类型为 cv T 或 cv T& 和 T 是 E 的明确公共基类,或

    — 处理程序的类型为 cv1 T* cv2 并且 E 是指针类型,可以 通过标准中的一个或两个转换为处理程序的类型 指针转换(4.10)不涉及到指针的转换 私有或受保护或模棱两可的类 — 资格转换

    ——处理程序是一个指针或指向成员类型的指针,E 是 std::nullptr_t。

    (强调我的)

    【讨论】:

      【解决方案2】:

      因为私有继承不允许您将Derived*/Derived&amp; 视为Base*/Base&amp;。这意味着您不能将 Derived* 放在应为 Base* 的位置。

      当你只想实现某个类而不接受它的接口时,实际上使用私有继承......

      【讨论】:

        【解决方案3】:

        是私有继承,MyException不能转换为std::runtime_error。

        【讨论】:

          猜你喜欢
          • 2011-04-16
          • 1970-01-01
          • 2010-12-06
          • 1970-01-01
          • 1970-01-01
          • 2010-12-12
          • 2011-12-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多