C++:如何将参数传递给自定义异常?

the*_*oon 9 c++ exception-handling exception

我创建了一个自定义异常:

class MyIOException : public std::exception
{
public:
  virtual const char* what() const throw()
  {
    return "IO Exception";
  } 
};
Run Code Online (Sandbox Code Playgroud)

class MyEmptyImageException : public MyIOException
{
private:
  std::string m_bucketName;
  std::string m_objectName;

public:

  MyEmptyImageException(const std::string& bn, const std::string& on) : m_bucketName(bn), m_objectName(on) {}
  virtual const char* what() const throw()
  {
    std::string msg = "Empty Image : " + m_bucketName + m_objectName;
    return msg.c_str();
  }  
};
Run Code Online (Sandbox Code Playgroud)

我试试这样:

int main(int argc, char** argv)
{
  try
  {
    // ... read image
    if (image.empty)
    {
      throw MyEmptyImageException(folderName, imageName);
    }
    // ... remained code
  }
  catch (MyEmptyImageException& meie)
  {
    std::cout << meie.what() << std::endl;
  }
  catch (std::exception& e)
  {
    std::cout << e.what() << std::endl;
  }
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不确定我是否做得对,你能纠正我,还是建议更好的实现,因为我是使用派生异常的初学者?

lri*_*eau 15

您已将参数正确传递给异常类的构造函数.

但是,该函数MyEmptyImageException::what()是错误的,因为它返回msg.c_str(),在msg堆栈上分配的位置.当函数what()返回时,它们的msg对象被销毁,char*指针指向由释放的对象管理的缓冲区.要解决这个问题,您可以在构造函数中构造消息MyEmptyImageException:

class MyEmptyImageException : public MyIOException
{
  std::string m_msg;
public:

  MyEmptyImageException(const std::string& bn, const std::string& on)
    : m_msg(std::string("Empty Image : ") + bn + on)
  {}

  virtual const char* what() const throw()
  {
    return m_msg.c_str();
  }
};
Run Code Online (Sandbox Code Playgroud)

  • 一个更好的解决方案不仅仅是使`msg`成为一个成员变量,而是在构造函数本身构造最终的消息.`MyEmptyImageException(const std :: string&bn,const std :: string&on):m_msg("Empty Image:"+ bn + on){}`.这允许你摆脱其他两个,现在`what()`的`throw()`保证是真的. (2认同)