【问题标题】:Optional Error Handling可选的错误处理
【发布时间】:2011-03-15 02:17:45
【问题描述】:

我有一个如下所示的 create 方法,我想(如果返回为空指针)从中获取错误。但是我希望这个错误处理是可选的,而不是调用函数的要求。

代码:

class foo {
    foo() {...};
public:
    ~foo();
    static foo* createFoo(int aparam = 42, int bparam = 10, int& error = ?) {
        afoo* = new foo();
        if (!afoo) {
            error = 11;
            return 0; //NULL
        }
        ...
        return afoo;
    }

}

所以我可以决定使用:

foo* myfoo = createFoo(42);
if (!myfoo) { ... }

或者

int errorcode = 0;
foo* myfoo = createFoo(42, 10, errorcode);
...

此时(在我的真实代码中),我只是使用空指针(而不是 ref)并在给它错误之前在 createFoo 代码中确定它的有效性。

我的兴趣在于这种情况下的最佳实践

【问题讨论】:

  • 虽然我没有很好地理解你的问题,但我认为解决方案在于用没有错误的版本重载你的函数。
  • @AbiusX 我认为这可能是最好的选择,我只是在寻求其他意见。
  • afoo永远为空。如果分配失败,new 会抛出 std::bad_alloc,如果分配失败,foo 的构造函数会抛出异常。
  • 谢谢詹姆斯,这只是一个例子,但我还是不知道 :)。

标签: c++ error-handling overloading


【解决方案1】:

我不知道我可以提供最佳实践,但这是我的观点。

检查 NULL(分配失败)是 C 和 C++ 中的标准做法,它是一种易于理解且易于识别的习语。添加一个可选的错误代码,同时提供灵活性也增加了可以说是不必要的复杂性。它让调用者决定他们是否将使用该参数。

他们为什么要使用该参数,除非他们认为在该位置可能失败?会怎样

如果您觉得错误代码很重要。我建议使用备用签名,即您始终检查返回代码,而不检查返回指针的值:

// Returns error code.
static int createFoo(int, int, Foo **);

这可能是一个不太方便的功能,但会将调用者(用户)推向正确的方向。

或者,您可以使用异常,或者确保抛出 std::bad_alloc,或者使用适当的错误代码抛出您自己创建的异常。这似乎是最干净的签名:

struct fooException { int error; }

// Throws fooException if cannot create foo.
static foo * createFoo(int, int);

我的理念是:尽量减少复杂性。在这种情况下,通过删除似乎无关的选项。 错误代码很重要并且应该始终使用,或者它无关紧要并且将始终被忽略。

【讨论】:

    【解决方案2】:

    当您通过引用传递某些内容时,您是在告诉该函数的用户这是一个必需参数。如果您想让错误代码成为可选,请传入一个指向 int 的指针并将其默认值设置为 null。

    static foo* createFoo(int aparam = 42, int bparam = 10, int* error = NULL)
    

    【讨论】:

    • 我明白了,并指出我目前正在使用这个解决方案。
    • 我误解了你的意思。我认为它指的是在调用 createFoo 之后检查 aFoo。在我看来,这是最好的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-06
    • 2015-01-06
    • 2016-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    相关资源
    最近更新 更多