简体   繁体   English

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

[英]C++ Custom exception throw () in constructor

So I read that you aren't supposed to have anything other than basic types in a custom exception class because otherwise it might throw an exception within the exception (like a dream within a dream). 所以我读到你不应该在自定义异常类中拥有除基本类型之外的任何东西,否则它可能会在异常中引发异常(就像梦中的梦一样)。 And that you should throw by value and catch by ref. 并且你应该按价值抛出并通过ref捕获。

I have this as my exception class header: 我将此作为我的异常类标题:

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

  private:
  // Error description
  const char* err;
};

But I dont like it since it introduces an issue with memory management, which is invisible to the naked eye and I need to use a mine detector. 但我不喜欢它,因为它引入了内存管理的问题,肉眼看不见,我需要使用探测器。 I would like to change to an std::string if possible. 如果可能,我想更改为std::string

But then there is the issue in the first paragraph above, so I thought about doing this: 但是上面的第一段中有问题,所以我想这样做:

#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;
};

Is this ok to do? 这样可以吗?

Using std::string can also give you a bad time with std::bad_alloc . 使用std::string也可以使用std::bad_alloc给你带来不好的时间。 But that problem is already inherent to std::runtime_error , as its constructors can take a std::string as an argument: 但是这个问题已经是std::runtime_error所固有的,因为它的构造函数可以将std::string作为参数:

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

It's only this way because copying exceptions shall never throw, so the implementation will likely allocate another string and copy the argument's content to it. 这只是这种方式,因为复制异常永远不会抛出,因此实现可能会分配另一个字符串并将参数的内容复制到它。 If you really don't want a second exception being thrown, mark your constructor as noexcept and make sure it never fails, and if it ever do, your program will be shut down immediately. 如果你真的不想抛出第二个异常,请将你的构造函数标记为noexcept并确保它永远不会失败,如果它曾经这样做,你的程序将立即关闭。

You can inherit std::runtime_error behavior by just constructing it with a string from your constructor like so: 您可以通过使用构造函数中的字符串构造它来继承std::runtime_error行为,如下所示:

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

At this point, you can remove your err data member, as runtime_error will give you the internal string which you can refer to by what() . 此时,您可以删除您的err数据成员,因为runtime_error将为您提供内部字符串,您可以通过what()引用该字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM