代码之家  ›  专栏  ›  技术社区  ›  SadSido

将可修改的参数传递给C++函数

  •  7
  • SadSido  · 技术社区  · 16 年前

    如果要将可修改的参数传递给函数,我应该选择什么:通过指针传递或通过引用传递?

    1. bool getfoo(foo&wheretoplacesult);
    2. bool getfoo(foo*wheretoplacesult);

    我这样问是因为我一直认为通过引用传递参数(1)是最佳实践,但是在检查了一些本地代码数据库之后,我得出了一个结论,最常见的方法是(2)。此外,该男子本人(bjarne stroustrup)建议使用(2)。(1)和(2)的优点是什么,还是仅仅是个人品味的问题?

    12 回复  |  直到 16 年前
        1
  •  22
  •   ChrisW    16 年前

    在以下情况下,我更喜欢引用而不是指针:

    • 不能为空
    • 它不能改变(指向其他东西)
    • 不得删除(由接收指针的人删除)

    有人说引用和常量引用之间的区别对很多人来说太细微了,在调用方法的代码中是看不见的(例如,如果您读取通过引用传递参数的调用代码,您就看不到它是常量引用还是非常量引用),因此您应该将其作为POINter(为了在调用代码中明确表示您要给出变量的地址,因此被调用方可能会更改变量的值)。

    我个人更喜欢推荐信,原因如下:

    1. 我认为一个例程应该知道它调用的是什么子例程
    2. 子例程不应该假定它是从哪个例程调用的。

    [1]意味着让调用者看到可变性并不重要,因为调用者应该已经(通过其他方式)理解子例程的作用(包括它将修改参数的事实)。

    [2]意味着如果它是指针,那么子例程应该处理参数为空指针的可能性,这可能是额外的和IMO无用的代码。

    此外,每当我看到一个指针,我就会想,“谁会删除这个,什么时候删除?”因此,无论何时/何地,所有权/生存期/删除都不是一个问题,我更喜欢使用引用。

    对于值得一提的是,我习惯于编写常量正确的代码:因此,如果我声明一个方法有一个非常量引用参数,那么它是非常量这一事实就非常重要。如果人们没有编写正确的常量代码,那么可能很难判断是否会在子例程中修改参数,而另一种机制(例如指针而不是引用)的参数会更强一些。

        2
  •  5
  •   T.E.D.    16 年前

    参考传递的优点:

    • 强制用户提供值。
    • 不易出错:处理指针取消引用本身。不必检查内部是否为空。
    • 使调用代码看起来更干净。

    按值传递指针的优点:

    • 允许为“可选”参数传递空值。有点难看,但有时有用。
    • 强制调用者知道参数正在执行什么操作。
    • 给读者半个线索,告诉他们在不必读取API的情况下,可以用参数做什么。

    因为引用传递使用的是语言,所以任何非指针参数也可能会被修改,而您不会 知道 指针值正在更改。我见过API,它们被视为常量。所以指针传递并不能真正给读者提供任何他们可以信赖的信息。对某些人来说,这也许足够好,但对我来说,却不够好。

    实际上,指针传递只是C留下的一个容易出错的杂乱的hack,它没有其他方法通过引用传递值。C++有一种方式,所以黑客不再需要了。

        3
  •  4
  •   luke    16 年前

    通过引用传递的一个优点是,它们不能为空(与指针不同),从而避免了对每个out参数进行空签出的需要。

        4
  •  3
  •   Fred Larson    16 年前

    我建议你 考虑 (可能不是对每种情况都最好)从函数返回foo,而不是修改参数。您的函数原型如下所示:

    Foo GetFoo() // const (if a member function)
    

    当您似乎返回成功/失败标志时,使用异常可能是更好的策略。

    优势:

    • 您可以避免所有指针/引用问题
    • 简化了呼叫者的生活。例如,可以在不使用局部变量的情况下将返回值传递给其他函数。
    • 如果抛出异常,调用方不能忽略错误状态。
    • 返回值优化意味着它可能和修改参数一样有效。
        5
  •  1
  •   Lou Franco    16 年前

    我选择2是因为在调用点很明显参数将被更改。

    getfoo(&var)而不是getfoo(var)

    对于常量引用,我更喜欢传递引用,在这里我试图避免复制构造函数调用。

        6
  •  1
  •   Rik Heywood    16 年前

    通过引用传递,并避免整个空指针问题。

        7
  •  0
  •   Preet Sangha    16 年前

    我似乎记得,在C++引用中,NULL和指针可能是空的。现在我已经很久没有做C++了,所以我的记忆力会生锈。

        8
  •  0
  •   StampedeXV    16 年前

    这里的差别相对较小。

    引用不能为空。

    可以传递空指针。 因此,您可以检查是否发生了这种情况并做出相应的反应。

    我个人无法想到这两种可能性中的一种真正的优势。

        9
  •  0
  •   erelender    16 年前

    我觉得这是个人品味的问题。实际上,我更喜欢引用传递,因为指针提供了更多的自由度,但它们也会导致很多问题。

        10
  •  0
  •   gbjbaanb    16 年前

    指针的好处在于,您不能传递任何内容,即,将其用作参数完全是可选的,并且没有调用方传递的变量。

    否则,如果您有一个引用,它保证存在并且是可写的(当然,除非是常量),则引用更安全。

    我认为这是一个优先事项,否则,但我不喜欢将两者混合,因为我认为这会使代码的维护和可读性变得更难(特别是当您的两个函数在调用方看来相同时)

        11
  •  0
  •   Nemanja Trifunovic    16 年前

    现在我使用常量引用作为输入参数,使用指针作为输出参数。FWIIW Google C++ Style Guide recommends the same approach (我并不总是同意他们的风格指南-例如他们不使用例外,这通常没有什么意义)

        12
  •  0
  •   Dima    16 年前

    我的偏好是推荐信。首先,因为它押韵。:)也因为其他答案指出的问题:不需要取消引用,引用也不可能为空。另一个我没有提到的原因是,当您看到一个指针时,您不能确定它是否指向动态分配的内存,您可能会试图调用 delete 关于它。另一方面,引用可以免除关于内存管理的任何歧义。

    尽管如此,在许多情况下,传递指针更可取,甚至是必要的。如果预先知道参数是可选的,那么允许它为空非常有用。类似地,您可能提前知道参数总是动态分配的,并且内存管理都已完成。