这种异常处理方式是否良好?

dan*_*uch 1 c++ exception-handling exception

你会改变这段代码中的任何内容吗?

class LocalPort {
public:
    LocalPort(int portNumber) {
      innerPort = new ACMEPort(portNumber);
   }

    void Open() {
      try {
          innerPort->Open();
      } 
      catch (DeviceResponseException& e) {
          throw PortDeviceFailure(e);
      } 
      catch (ATM1212UnlockedException& e) {
         throw PortDeviceFailure(e);
      } 
      catch (GMXError& e) {
         throw PortDeviceFailure(e);
      }
   } 
private: 
    ACMEPort* innerPort;
};

/////////

try {
    LocalPort* port = new LocalPort(12);
    port->Open();
} 
catch (bad_alloc& e) {
    ReportError(e);
    logger.Log("Wyj?tek alokacji pami?ci", e);
    delete port;
}
catch (PortDeviceFailure& e) {
    ReportError(e);
    logger.Log(e.getMessage(), e);
    delete port;
} 
Run Code Online (Sandbox Code Playgroud)

上面尝试的是让下面的代码看起来更好.

try {
    ACMEPort* port = new ACMEPort(12);
    port->Open();
} 
catch (bad_alloc& e) {
    ReportPortError(e);
    logger.Log("Wyj?tek alokacji pami?ci", e);
    delete port;
}
catch (DeviceReponseException& e) {
    ReportPortError(e);
    logger.Log("Wyj?tek odpowiedzi urz?dzenia", e);
    delete port;
} 
catch (ATM1212UnlockedException& e) {
    ReportPortError(e);
    logger.Log("Wyj?tek odblokowania", e);
    delete port;
} 
catch (GMXError& e) {
    ReportPortError(e);
    logger.Log("Wyj?tek odpowiedzi urz?dzenia");
    delete port;
}
catch (...) {
    ReportPortError(0);
    logger.Log("Wyj?tek nieznanego pochodzenia");
    delete port;
}
Run Code Online (Sandbox Code Playgroud)

我成功了吗?第一个比第二个好吗?你怎么看?

Bjö*_*lex 7

看起来你设计的异常类很糟糕.为什么不简单地将一个成员函数添加getMessage到异常层次结构中(最好是在基类中,所有异常派生自 - std::exception提供what返回错误消息的方法).这样,您可以简单地在一个语句中捕获所有异常,并以相同的方式处理它们.

class DeviceResponseException : public std::runtime_error {
public:
    DeviceResponseException() : std::runtime_error("Some error message") {}
};

class ATM1212UnlockedException : public std::runtime_error {
public:
    ATM1212UnlockedException() : std::runtime_error("Some other error message") {}
};
Run Code Online (Sandbox Code Playgroud)

然后在您的代码中,您可以这样做:

try {
    std::auto_ptr<ACMEPort> port(new ACMEPort(12));
    port->Open();
}
catch( std::runtime_error & e) {
    ReportPortError(e);
    logger.Log(e.what(), e);
}
Run Code Online (Sandbox Code Playgroud)

由于你的异常类都来自std::runtime_error,所以这个catch-clause捕获它们.这没关系,因为所有情况下的处理都是一样的.如果您有需要特殊处理的特定异常,则添加其他catch-clauses.

此外,而不是调用delete port的异常处理程序,你应该使用一个std::auto_ptr或者boost::scoped_ptr还是那种东西.了解RAII.