什么是一组异常类的好设计?
我看到各种各样的东西,关于什么异常类应该和不应该做什么,但不是一个简单的设计,易于使用和扩展,做那些事情.
让1和4一起工作是我遇到的最大问题,因为任何格式化和文件输出方法都可能失败.
编辑:所以看了几个类中的异常类,并且在Neil链接的问题中,似乎通常的做法是完全忽略第1项(因此提升建议),这似乎是一个相当糟糕的想法我.
无论如何,我以为我也会发布我正在考虑使用的异常类.
class Exception : public std::exception
{
public:
// Enum for each exception type, which can also be used
// to determine the exception class, useful for logging
// or other localisation methods for generating a
// message of some sort.
enum ExceptionType
{
// Shouldn't ever be thrown
UNKNOWN_EXCEPTION = 0,
// The same as above, but it has a string that
// may provide some information
UNKNOWN_EXCEPTION_STR,
// For …Run Code Online (Sandbox Code Playgroud) 在我编写的大多数代码库中非常常见的两种反模式是布尔返回值以指示成功/失败,以及通用整数返回代码以指示有关错误消息的更多详细信息.
这两个都非常类似于C,并且在我的拙见中不能很好地适应C++.
我的问题是关于在代码库中设计异常时的最佳实践.换句话说,表明失败的有限可能性的最佳方法是什么?例如,上述反模式之一通常会有一个巨大的枚举,每个枚举值代表一种特定类型的失败,例如FILE_DOES_NOT_EXIST或NO_PERMISSIONS.通常这些保持尽可能通用,以便它们可以跨多个不相关的域(例如网络组件和文件I/O组件)使用.
类似于此的设计可以考虑用于异常是std::exception为每种类型的故障或可能出错的事物子类化一个具体的异常类型.所以在我之前的例子中,我们将有以下内容:
namespace exceptions {
class file_does_not_exist : public std::exception {};
class no_permissions : public std::exception {};
}
Run Code Online (Sandbox Code Playgroud)
我认为这更接近"感觉更好"的东西,但最终这似乎是一个维护噩梦,特别是如果你有数百个这样的"错误代码"转换成类.
我看到的另一种方法是简单地使用标准<stdexcept>类,例如std::runtime_error并且具有包含细节的字符串.例如:
throw std::runtime_error( "file does not exist" );
throw std::runtime_error( "no permissions" );
Run Code Online (Sandbox Code Playgroud)
这种设计更易于维护,但如果它们都可能从相同的核心位置或函数调用中被抛出,则有条件地捕获这些异常中的任何一个是困难的或不可行的.
那么什么是异常类型的良好,可维护的设计?我的要求很简单.我想要了解发生了什么的上下文信息(我的内存耗尽了吗?我是否缺少文件系统权限?我是否未能满足函数调用的前提条件(例如,错误的参数)?),我也喜欢能够相应地对该信息采取行动.也许我对待所有这些都是一样的,也许我对某些失败有特定的捕获语句,所以我可以用不同的方式从它们中恢复.
我对此的研究只引出了这个问题: C++异常类设计
这里的用户问我一个类似的问题,他/她底部的代码示例几乎是可爱的,但他/她的基本异常类不遵循开放/封闭原则,所以这对我来说不起作用.