最佳实践 - 从函数返回指针

3
我有一个困惑,当函数可能失败时,应该如何从函数返回智能指针。以下是几种选项:
  1. 如果函数失败,则返回指针并抛出异常:
    std::shared_ptr foo() {
        // ...
        if (!ok)
          throw;
        return ptr;
    }

  1. 如果函数失败,则返回空指针:
    std::shared_ptr foo() {
        // ...
        if (!ok)
            return std::shared_ptr();
return ptr; }
  1. 通过引用传递指针,并返回布尔标志:
    bool foo(std::shared_ptr& ptr) {
        // ...
        if (ok)
            ptr = ...;
return ok; }

是否有最佳实践或指南来报告函数未正确执行?还是这通常是项目特定的?

感谢您的回答。


1
非常相关:当检索方法无法生成返回值时,应该返回“null”还是抛出异常? - emlai
1
任何答案都将高度基于个人意见。然而,无论是否有人同意您的决定,请确保行为已记录。 - James Adkison
2
不要使用 #3,#1 更好;它可以防止调用者忘记处理错误。#2 可以接受,因为调用者必须检查 null 值。通常情况下,这些都不是硬性规则,因为有时您的环境会施加额外的限制(例如异常太慢/不存在等)。 - GManNickG
1
绝对不是第三个,输出参数很糟糕。第一个需要实际抛出异常,否则如果你在没有活动异常的情况下使用throw;,程序将终止。第一个和第二个都可以,但某些代码库不允许使用异常,在这种情况下,第二个选项是您唯一的选择。我的首选是使用第二个选项,除非这是一种情况,在这种情况下,如果foo()失败,调用者可能无法做出明智的选择,那么您应该选择第一个选项。 - Praetorian
由于智能指针可以为空,如果现在不是使用该功能的正确时间,那么什么时候才是呢? - emlai
显示剩余2条评论
2个回答

1
说实话,正确的答案取决于所调用的函数做什么以及失败的后果。对于库,我建议抛出异常或返回指示失败的值。通过引用传递指针并返回标志似乎有些可疑,除非您经常使用该习语,或者有理由在外部管理共享指针。

-1

好问题。我认为这取决于错误的发生或性质。 如果你预见到这种错误会偶尔发生,或者它是一种预期的错误,甚至是一种可以通过某种方式恢复的错误,那么我会使用第二或第三种方法。

然而,如果错误是不应该经常发生的,并且会导致应用程序无法正常运行,我会使用第一种方法。

我的理由是异常可能比其他两种方法慢(请参见 C++中的异常真的很慢吗),并且按照自然规律,异常会向上流动到主调用者,因此您希望关键错误向上移动并停止进程。


4
"证明例外处理相较于另外两种方法更慢。" - Captain Obvlious
也许我应该说,它通常会更慢,但并非总是如此。 - ArmenB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接