Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 这是处理异常的好方法吗?_C++_Exception_Exception Handling - Fatal编程技术网

C++ 这是处理异常的好方法吗?

C++ 这是处理异常的好方法吗?,c++,exception,exception-handling,C++,Exception,Exception Handling,你能修改一下这个代码吗 class LocalPort { public: LocalPort(int portNumber) { innerPort = new ACMEPort(portNumber); } void Open() { try { innerPort->Open(); } catch (DeviceResponseException& e) { th

你能修改一下这个代码吗

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;
} 
我试图在上面做的是使下面的代码看起来和行为更好

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;
}
我成功了吗?第一个比第二个好吗?你觉得怎么样?

是的,我会:

  • 只有一个异常类,因此:
  • 不将异常从一种类型转换为另一种类型
  • 捕获代码中更高级别的异常,因此:
  • 不会编写比实际代码更多的异常处理代码
  • 我不会使用new创建对象,如果我这样做了,我会使用智能指针
基本上,我认为您完全误解了如何使用异常

您可以对代码进行的最佳单个更改是替换:

ACMEPort* port = new ACMEPort(12);
port->Open();
与:

同样,在其他地方,捕获异常的需求也随之消失。

是的,我会:

  • 只有一个异常类,因此:
  • 不将异常从一种类型转换为另一种类型
  • 捕获代码中更高级别的异常,因此:
  • 不会编写比实际代码更多的异常处理代码
  • 我不会使用new创建对象,如果我这样做了,我会使用智能指针
基本上,我认为您完全误解了如何使用异常

您可以对代码进行的最佳单个更改是替换:

ACMEPort* port = new ACMEPort(12);
port->Open();
与:


同样,在其他地方,捕获异常的需求也随之消失。

看起来您的异常类设计得很糟糕。为什么不简单地将一个成员函数
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") {}
};
然后在代码中,可以执行以下操作:

try {
    std::auto_ptr<ACMEPort> port(new ACMEPort(12));
    port->Open();
}
catch( std::runtime_error & e) {
    ReportPortError(e);
    logger.Log(e.what(), e);
}
试试看{

std::auto_ptr.

看起来您的异常类设计得很糟糕。为什么不简单地向异常层次结构中添加一个成员函数
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") {}
};
然后在代码中,可以执行以下操作:

try {
    std::auto_ptr<ACMEPort> port(new ACMEPort(12));
    port->Open();
}
catch( std::runtime_error & e) {
    ReportPortError(e);
    logger.Log(e.what(), e);
}
试试看{

std::auto_ptr.

我会将异常处理程序移动到类中,让类处理错误,而不是强制所有调用方处理错误。这样,您可以通过检查Open()的结果值来清除指针(如果出于某种原因确实需要指针):


我会将异常处理程序移动到类中,让类处理错误,而不是强制所有调用方处理它。这样,您可以通过检查Open()的结果值来清除指针(如果出于某种原因确实需要指针):


任何关于如何使其“更好”的建议都非常受欢迎:)@Space\u C0wb0y:同意。理想情况下,我们应该为codereview进行自动迁移。@dantuch:在
端口
存在的唯一作用域中,您从未
删除端口。您已经尝试在
捕获
处理程序中执行此操作(但不适用于没有抛出异常的情况;这可能是在您的代码中稍后完成的,您没有将其包含在如此不准确的示例中),但据我所知,它不会编译(或者,您有另一个名为
port
的变量,位于作用域层次结构的更上一层,您意外地
delete
ing,可能会调用UB).Summary:要么是其他内容的双重免费,要么是编译错误。@Closer:为什么会偏离主题?@Johnsa理解,因为它包含工作代码,他要求对其进行代码审查。因此,对于SE来说,它太本地化了,但非常适合上述其他网站。如果它被修改为询问特定问题,而不是“您会对此代码进行哪些更改?”它可能适合此处。欢迎提供任何如何使其“更好”的建议:)@Space_C0wb0y:同意。理想情况下,我们应该为codereview进行自动迁移。@dantuch:在
端口
存在的唯一作用域中,您从未
删除端口
。您尝试在
捕获
处理程序中执行此操作(但不适用于没有抛出异常的情况;这可能是在您的代码中稍后完成的,您没有将其包含在如此不准确的示例中),但据我所知,它不会编译(或者,您有另一个名为
port
的变量,位于作用域层次结构的更上一层,您意外地
delete
ing,可能会调用UB).Summary:要么是其他内容的双重免费,要么是编译错误。@Closer:为什么会偏离主题?@Johnsa理解,因为它包含工作代码,他要求对其进行代码审查。因此,对于SE来说,它太本地化了,但非常适合上述其他网站。如果它被重新修改以询问特定问题,而不是你会对这段代码做什么修改?“它可能适合这里。你能提供一些(真的)吗可以改进我的代码的快速更改?如果需要一些时间,请不要介意我的静默。你不应该只有一个异常类。但是,你应该为所有异常类都有一个单独的基类。@空间观点。我多年来一直使用一个异常类。@Space\u Cowb0y:我通常有零/一每个库的异常类。除非有一些非常特定的异常类型可以单独捕获和处理以进行更正。因此,尽管构建异常层次结构的概念在实践中很好,但很少(并且我们有std::exception作为公共基础)。您能提供一些(真的)快速更改可以改进我的代码?如果需要一些时间,请不要介意我的静默。你不应该只犯一个错误