6

我正在开发一个系统,该系统旨在使用名为error_code,error_conditionerror_category- 一个新的方案 std: 在 C++11 中,尽管目前我实际上正在使用 Boost 实现。我已经阅读了 Chris Kholkoff 的系列文章,现在已经三遍了,我想我大致了解了如何创建这些类。

我的问题是该系统需要处理存在于单个 DLL 中的插件,并且这些插件可能会出现错误。我最初的设计是计划一个特定于系统的错误类别,该类别将包含所有各种错误代码和一个不真正映射到errno值的特定错误条件的候选清单。这里的问题是,要使 DLL 能够使用这些错误代码之一,它需要访问error_category应用程序中的唯一实例。我现在通过SetErrorCategory()从每个 DLL 导出一个函数来处理这个问题,这个函数可以工作,但有点恶心。

我看到的替代解决方案是每个 DLL 都有自己的错误类别和代码,如果需要,还有自己的条件;我怀疑这更像是为这个库功能所设想的。但是,我认为这需要主应用程序的错误方案中的比较功能,该功能了解插件的错误方案,并可以检查应用程序的哪些条件与插件的错误匹配。这似乎更容易出现一堆问题,尽管我还没有尝试实现它。我猜我必须在所有实际逻辑之上从 DLL 中导出整个错误方案。

当然,另一种方法是仅使用 DLL 中的数字错误代码并将它们填充到应用程序端的错误对象中。它具有插件简单的优点,但可能会导致应用程序中的陷阱(例如,处理来自几个不同插件的对象的函数需要注意每个错误的来源)。

所以我的具体问题是:在这三个选项中,你会使用哪个,为什么?哪个明显行不通?当然,我还没有想到更好的方法吗?

4

2 回答 2

2

我在处理这个问题时得到的解决方案是使用预定义的代码来处理问题系列和用户子代码选择以及特定类型错误的继承。通过 boost 这让我可以通过以下方式继承特定类型:

struct IOException : virtual std::exception, virtual boost::exception {};
struct EOFException : IOException {};
...

并保留与预定义的一般错误(如 IOException)匹配的错误代码。因此,我可以为每个错误系列提供一个通用代码范围:

namespace exception { namespace code {
    UNKNOWN_EXCEPTION           = 0;
    IO_EXCEPTION                = 100;
    CONCURRENCY_EXCEPTION       = 200;
    ...
}}

然后,如果有人想要一个新的错误类型,他们可以从已经定义的通用异常类型和伴随该错误的代码继承,并通过继承类型和次要值 (0-99) 专门化异常。这也允许 try catch 块捕获更具体的错误类型,同时让更通用的异常版本传递给其他控制块。然后,用户可以自由使用父异常代码或指定他们自己的代码,该代码在家族中(父 = 100 -> 子 = 115)。如果用户只想要一个 IOError,而不创建新的错误系列,他们可以使用默认的系列异常,没有任何麻烦。我发现这给了用户灵活性,而不需要在他们不想要的时候对异常代码进行 OCD 跟踪。

然而,这绝不是最终的解决方案,因为个人喜好导致了我在这里的设计选择。我发现有太多的错误代码会让人感到困惑,并且异常继承已经对这些信息进行了编码。实际上,在我描述的系统中,完全去除错误代码并仅依赖异常继承是很容易的,但许多人更喜欢为每个异常名称分配一个代码。

于 2012-08-29T01:15:35.750 回答
2

我想出了另一种解决方案:创建一个仅包含我的error_category实现的 DLL,并从应用程序和每个插件 DLL 链接到它。这使他们可以访问全局类别对象,而无需将该对象从应用程序显式传递给 DLL。

于 2012-09-14T22:40:46.197 回答