【发布时间】:2016-01-14 17:08:39
【问题描述】:
这个问题与c++ Exception Class Design类似,如下:
我想为我的应用程序设计异常类层次结构,这里是我使用的设计点:
异常应派生自标准异常类(即
std::exception、std::logic_error和std::runtime_error)。异常类应该能够获取错误描述(即所谓的
what)和错误发生的位置(const std::string &file, int line)Exception 不应在构造期间或从任何其他成员引发任何异常。
鉴于此,我有:
#define throw_line(TException, what) throw TException((what), __FILE__, __LINE__)
class AnException : public std::exception {
public:
AnException(const std::string &what, const std::string &file, int line) noexcept {
try {
what_ = what;
file_ = file;
line_ = line;
} catch (std::exception &e) {
was_exception_ = true;
}
}
virtual ~AnException() noexcept {}
virtual const char *what() const noexcept override {
if (was_exception_) {
return "Exception occurred while construct this exception. No further information is available."
} else {
try {
std::string message = what_ + " at " + file_ + ":" + std::to_string(line);
return message.c_str();
} catch (std::exception &e) {
return "Exception occurred while construct this exception. No further information is available."
}
}
}
};
class ParticularException : public AnException {
...
}
如您所见,构造这样的类似乎有些复杂,因为我们绝对不应该在构造函数(否则将调用 std::terminate())或 what() 成员中出现异常。
问题:这个例子是一个好的设计还是我应该删除一些限制(比如,有文件/行信息)来简化它?有没有更好的办法?
我可以随意使用 C++11/C++14,但尽量不要使用 C++17,因为它尚未完成,编译器可能无法完全实现它。
注意:我希望这段代码是跨平台的。
提前致谢。
编辑 1: 后续问题:我如何停用文件/行信息,但将其保留在日志中?可能打印堆栈跟踪是比我现在拥有的更好的解决方案?我的意思是离开仅包含错误消息 (what) 的异常类,并在异常处理链的上层调用 print_backtrace 之类的东西。
【问题讨论】:
-
FILE 通常扩展为文字。这意味着您应该能够使用... template
constructor(const char (&array)[N])... ...这可以防止异常。您可以以类似的方式强制使用文字。 -
请参阅stackoverflow.com/a/24520735/576911 了解如何使您的异常复制构造函数为 noexcept。
标签: c++ c++11 exception exception-handling c++14