【问题标题】:Assignment by value vs by reference?按值分配与按引用分配?
【发布时间】:2020-07-29 16:04:54
【问题描述】:
SomeStruct getSomeStruct();

const SomeStruct a = getSomeStruct();
const SomeStruct &b = getSomeStruct();

我了解按值传递按引用按常量引用之间的区别。我的问题是,上面的示例与将参数传递给函数时相同吗?所以b的赋值更快,因为它不需要复制数据,不像a的赋值?

【问题讨论】:

标签: c++


【解决方案1】:

所以b的赋值更快,因为它不必复制数据,不像a的赋值?

没有。在复制方面没有区别。

您正在做的是将引用绑定到临时对象。在这种特殊情况下,临时对象的生命周期超出了完整表达式,以匹配引用的生命周期。该程序的行为实际上与您没有使用引用相同。在这里使用引用的缺点是程序员可能会对其含义感到困惑,除非他们知道此生命周期扩展规则。

当您知道函数不返回引用时,没有理由使用这样的引用。如果函数确实返回了引用,那么您将避免使用引用进行复制。复制比通过引用的间接复制快还是慢取决于类型。

生命周期延长有用的情况是在模板中,您不知道函数是返回引用还是引用包装器(这是一个对象,即不是引用,但在某些方面表现得像引用,因为重载运算符)。临时生命周期延长允许两种情况的行为方式相同。

【讨论】:

    【解决方案2】:

    在扩展的 eeroika 答案中,扩展规则的生命周期有例外:

    • 未扩展在 return 语句中临时绑定到函数的返回值。该值在返回表达式完成执行后立即销毁,并导致悬空引用
    • 在函数调用中与引用参数的临时绑定一直存在,直到包含该函数调用的完整表达式结束:如果函数返回的引用比完整表达式的寿命长,则它成为悬空引用。
    • 在 new 表达式中使用的初始化程序中的引用的临时绑定一直存在到包含该 new 表达式的完整表达式的末尾,而不是与初始化的对象一样长。如果初始化的对象比完整的表达式寿命更长,它的引用成员就会变成一个悬空引用。

    现在,如果您使用的是 c++14 或更低版本,您还可以:

    • 绑定到构造函数初始值设定项列表中的引用成员的临时绑定仅持续到构造函数退出,而不是只要对象存在。 (注意:从 DR 1696 开始,此类初始化格式不正确)。

    他们在 c++20 中添加了:

    • 使用直接初始化语法(括号)而不是列表初始化语法(大括号)初始化的聚合的引用元素中的引用的临时绑定一直存在,直到包含初始化程序的完整表达式结束。

    这些都来自这个网站:CPP Reference

    您还需要注意这些异常,以防止使用悬空引用。

    【讨论】:

      猜你喜欢
      • 2020-04-17
      • 2017-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-28
      • 2010-12-27
      相关资源
      最近更新 更多