我正在尝试获取我的 C++ 应用程序的错误代码列表,以便在多个项目之间共享错误。每个错误仅包含一个唯一的代码(用于提供给
exit()
和类似代码)和要显示的消息。除了构造函数和一些转换方法之外,我还需要一些函数来通过其代码获取错误,以便当程序 A 退出时我可以读取程序 B 的返回代码并将其显示给用户/日志/其他内容。显然,这意味着要跟踪整个错误列表。为此,我在 Error 类中保留一个静态 std::unordered_map
,以便 Error 构造函数将正在创建的实例添加到其中。但是,由于某种原因我不太明白,在将 Error
添加到地图时,我不断收到空指针取消引用错误。我的代码如下:
错误代码.h
namespace ErrorCodes{
class Error{
private:
int code;
std::string message;
static int counter;
static std::unordered_map<int, Error*> allErrors;
Error(int code, std::string message);
public:
Error(): code(1), message(""){}
explicit Error(std::string message);
Error getByCode(int code);
operator int() const{
return code;
}
operator std::string() const{
return message;
}
std::ostream& operator<<(std::ostream& os)
{
os << std::string("ERR_")+std::to_string(code)+std::string(": ") + message;
return os;
}
operator QString() const{
return QString::fromStdString(message);
}
bool operator == (Error other){
return other.code == code;
}
};
//List all errors here
const Error ERR_ERROR_CODE_NOT_FOUND("Couldn\'t find error with code %1"); //Follow QString formatting style for more complex messages
const Error ERR_GLOBAL_ID_NOT_FOUND("Problem with the global Id, identifier not found.");
const Error ERR_DIR_NOT_FOUND_OR_CREATED("Dir not found or created, check configuration.");
}
然后是我的 error_codes.cpp:
using namespace ErrorCodes;
int Error::counter = 0;
std::unordered_map<int, Error*> Error::allErrors = std::unordered_map<int, Error*>();
Error::Error(int code, std::string message) : code(code), message(message){
std::pair pair = std::make_pair(code, this);
allErrors.emplace(pair); //It fails here
}
Error::Error(std::string message){
int code = --counter;
Error(code, message);
}
Error Error::getByCode(int code){
auto it = allErrors.find(code);
if(it!=allErrors.end()){
return *(it->second);
}else{
qCritical() << QString(ERR_ERROR_CODE_NOT_FOUND).arg(code);
exit(ERR_ERROR_CODE_NOT_FOUND);
}
}
PS:理想情况下,我不会将
Error
创建为一个类,而是一个结构,并拥有某种包含所有错误的集合(例如数组),并允许我通过错误检索它们代码。但是,我没有找到一种方法可以在数组中提供错误并作为“常量”(以便在代码中的任何位置我都可以编写 ErrorCodes::XXX
),而不必手动创建包含所有 Error
的数组s(例如,枚举非常适合此目的)。如果其他人知道更好的方法来做到这一点,我将不胜感激。
似乎您使用了错误的委托构造函数语法
Error::Error(std::string message){
int code = --counter;
Error(code, message); //temporary
}
应该是
Error::Error(std::string message) : Error(--counter, message) {}
否则,您将构造一个临时错误,该错误仅存在于委托构造函数的堆栈帧中,当退出构造函数时,临时错误的“this”指针指向无效的内存区域。
我不太清楚为什么仅使用此代码就可以直接得到分段错误,而不是在尝试从地图中取消引用错误时得到它,但这是一个很好的起点。