【问题标题】:C++11 return error code from functionC++11从函数返回错误代码
【发布时间】:2013-05-29 15:55:22
【问题描述】:

例如,我有一些带有Load() 函数的课程。

class DB {
private:
    pt_db *db;
public:
    DB(const char *path);
    Write(const char *path);
    int Load(const char *path);
};

我想根据传递的参数从 Load() 函数返回一些状态。

例如:

Load(<correct path to the file with valid content>) // return 0 - success
Load(<non-existent path to file>) // return 1
Load(<correct file path, but the content of the file is wrong>) // return 2

不过我也很担心:

  1. 类型安全 - 我的意思是我想返回一些只能用作状态码的对象。

    int res = Load(<file path>);
    
    int other  = res * 2; // Should not be possible
    
  2. 仅使用预定义的值。使用int,我可以错误地返回一些其他状态,例如return 3(让我们建议Load() 函数中发生了错误),如果我不希望这个错误代码会被传递:

    int res = Load(<file path>);
    
    if(res == 1) {}
    
    else if (res == 2) {};
    
    ...
    
    // Here I have that code fails by reason that Load() returned non-expected 3 value
    
  3. 使用最佳 C++11 实践。

有人可以帮忙吗?

【问题讨论】:

  • enum class 会这样做吗?
  • 异常是发出失败信号的常用方法。它们的优点是您不能(意外地)忽略它们并假设成功,并且它们可以编码尽可能多的信息。
  • 我只是想知道一些可能的解决方案。为什么 C++11 有 std::error_code?另外我建议这段代码可以用在C代码中,C不能处理异常。
  • @user966467,无论如何,您都必须将其包装起来才能在 c 中使用它...
  • @user966467: 标准库使用error_code 以标准化方式报告系统错误,方法是抛出包含error_codesystem_error。此外,您不能直接使用 C 中的代码,因为 C 也不能处理类。

标签: c++ c++11 error-handling


【解决方案1】:

枚举是返回状态的好方法,例如:

class Fetcher{
public:
 enum FetchStatus{ NO_ERROR, INVALID_FILE_PATH, INVALID_FILE_FORMAT };
private:
 FetchInfo info;
public:
 FetchStatus fetch(){
    FetchStatus status = NO_ERROR;
    //fetch data given this->info
    //and update status accordingly
    return status;
 }
};

另一种方法是使用异常

class Fetcher{
private:
 FetchInfo info;
public:
 void fetch(){
    if file does not exist throw invalid file path exception
    else if file is badly formatted throw invalid file format exception
    else everything is good
}

使用枚举作为返回状态更多的是 C 方式,使用异常可能更多的是 C++ 方式,但这是一个选择问题。我喜欢 enum 版本,因为我认为它的代码更少且更具可读性。

【讨论】:

  • 还可以在函数结果中添加__attribute__((warn_unused))(至少在 gcc 和 clang 中),确保返回码不会被忽略。不幸的是,没有检查 C++ 异常,因此仍有可能出错(有 RAII,但它主要保护资源分配 - 终止代码可能会导致更微妙的问题)。
  • 混合异常和错误代码是否可以接受?例如,从 DB 构造函数抛出异常,如果 Load() 失败返回错误代码,因为在这种情况下,我不会更新内部对象数据,它将指向创建对象时的旧数据?
  • 这完全取决于你,这不一定是一个坏主意,尽管考虑坚持一致的方法。
猜你喜欢
  • 2022-11-07
  • 1970-01-01
  • 1970-01-01
  • 2018-01-20
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
相关资源
最近更新 更多