C++ 构造函数中的自定义异常抛出 ()

C++ Custom exception throw () in constructor

本文关键字:自定义异常 构造函数 C++      更新时间:2023-10-16

所以我读到在自定义异常类中除了基本类型之外不应该有任何其他类型,否则它可能会在异常中抛出异常(就像梦中的梦(。并且您应该按值抛出并按引用捕获。

我有这个作为我的异常类头:

class DeepthroatException : public std::runtime_error {
  public:
  DeepthroatException(const char* err); // set err member to err
  private:
  // Error description
  const char* err;
};

但我不喜欢它,因为它引入了内存管理问题,这是肉眼看不见的,我需要使用地雷探测器。如果可能的话,我想改成std::string

但是上面第一段有问题,所以我想这样做:

#include <string>
class DeepthroatException : public std::runtime_error {
  public:
  DeepthroatException(std::string err) throw(); // set err member to err, no throw
  private:
  // Error description
  std::string err;
};

可以这样做吗?

使用std::string也会让你在std::bad_alloc上度过一段糟糕的时光。但是这个问题已经是std::runtime_error固有的,因为它的构造函数可以把std::string当作参数:

explicit runtime_error( const std::string& what_arg );
explicit runtime_error( const char* what_arg );

之所以如此,是因为复制异常永远不会引发,因此实现可能会分配另一个字符串并将参数的内容复制到其中。如果您确实不希望抛出第二个异常,请将构造函数标记为 noexcept 并确保它永远不会失败,如果失败,您的程序将立即关闭。

您可以通过使用构造函数中的字符串构造std::runtime_error行为来继承它,如下所示:

DeepthroatException(const std::string& err) noexcept :
    std::runtime_error(err)
{
    // ...
}

此时,您可以删除err数据成员,因为runtime_error将为您提供内部字符串,您可以通过what()引用该字符串。