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作为公共基础)。您能提供一些(真的)快速更改可以改进我的代码?如果需要一些时间,请不要介意我的静默。你不应该只犯一个错误