我想就在 C++ 中处理静态错误字符串的最佳方法提出意见。我目前正在使用许多常量 char 指针,但它们变得笨拙,并且它们分散在我的代码中的每个地方。我还应该为这些字符串使用静态常量字符指针吗?
我正在考虑使用 SimpleIni 类来实现跨平台兼容性的定义、哈希表和 INI 文件。该项目是一个始终运行的 Web 服务器。
我想使用错误编号或名称来逻辑地引用它们。
如果有帮助,我将使用命名空间类中包含的全局空间和方法。如果环境也有帮助,代码将导出到 C。
谢谢
首先,您可以在stackoverflow上查看其他相关问题。这里有一些:
然后看看这个关于错误处理的精彩教程(它是一个由五部分组成的教程,但您可以从该链接访问所有这些教程)。如果您使用的是 C++11,这将特别有趣,因为它提供了更多用于错误处理的功能。或者,如果您不能使用 C++11,则可以使用boost 。
您还需要考虑是否要包括对本地化的支持。如果您的应用程序可能会以不同的语言向用户显示消息,那么最好从一开始就将该要求也包含在错误管理中。例如,您可以为此检查Boost.Locale。
这里有几件事情很紧张,所以让我列举一下:
一般来说,我见过的最简单的事情是使用一些整数常量来识别错误,然后在一侧有一个表格,您可以在其中检索其他信息(可能很多信息)。例如,Clang 使用该系统进行诊断。您可以通过使用对您有利的预处理器来避免重复自己。
使用这样的标题:
#define MYMODULE_ERROR_LIST \
ERROR(Code, "description") \
...
#define ERROR(Code, Desc) Code,
class enum ErrorCode: unsigned {
MYMODULE_ERROR_List
NumberOfElements
};
#undef ERROR
struct Error {
ErrorCode code;
char const* description;
};
Error const& error(ErrorCode ec);
还有一个简单的源文件来定位数组:
#define ERROR(Code, Desc) { Code, Desc },
Error const ErrorsArray[] = {
MYMODULE_ERROR_LIST
{ErrorCode::NumberOfElements, 0}
};
Error const& error(ErrorCode const ec) {
assert(unsigned(ec) < unsigned(ErrorCode::NumberOfElements) &&
"The error code must have been corrupted.");
return ErrorsArray[ec];
} // error
注意:在标头中定义宏的代价是描述中措辞的最轻微变化意味着根据枚举重新编译所有代码。就个人而言,我的东西比它测试的构建速度要快得多,所以我不太在意。
这是一个相当有效的方案。由于它尊重 DRY(不要重复自己),它还确保代码描述映射是准确的。ERROR
可以调整宏以获得更多信息,而不仅仅是描述(类别等)。只要Error
type is_trivially_constructible
,可以静态初始化数组,从而避免生命周期问题。
不幸的是,enum
它并不擅长模块化。enum
并且在统一处理错误时,让每个模块都运行自己的模块很快就会变得无聊(Error
结构可以使用unsigned code;
)。
如果您希望超越中央存储库,则需要更多涉及的机制,但由于它似乎适合您,我将停止提及此限制。
我会保持简单,在标题中:
enum ErrorCode { E_help, E_wtf, E_uhoh };
const char* errstr(ErrorCode);
然后在一些.c
或.cc
文件中:
const char* error_strings[] = {
"help!",
"wtf?",
"uh-oh"
};
const char* errstr(ErrorCode e) { return error_strings[e]; }
您的问题没有太多细节,但是根据您发布的内容,我会考虑使用单例类来处理您的错误消息。您可以创建通过代码或枚举访问消息的方法。然后,您可以实现国际化或您的特定应用程序所需的任何其他内容。此外,如果您决定将来使用 SQLite 或其他基于文件的解决方案,类接口可以保持不变(或扩展),从而最大限度地减少对其余代码的影响。