【问题标题】:Why can't a reference's target object be reasigned?为什么不能分配引用目标对象?
【发布时间】:2013-12-15 21:58:31
【问题描述】:

如果我理解正确的话,引用的动机是让“通过引用”工作变得更容易和更清晰,而不必为指针取消引用而烦恼。但是它们本质上是常量,它们只能指向一个对象,即使实际上引用是一个指针并且重新分配在技术上是可能的。如果引用可以为空,这似乎也是有益的,例如在使用它之前检查返回的引用是否有效,但这不是一个功能。

省略这些特性并按原样呈现特性背后的特殊动机可能是什么?

【问题讨论】:

  • 关于“如果引用可以为空,例如检查返回的引用是否有效,在使用它之前似乎也有好处”:支持空引用如何帮助检查有效性?空指针是有效的。无效的悬空指针不为空且不可检查。我认为引用也是一样的,是吗?
  • 更好,因为引用不能为“null”,你甚至不必检查任何东西!
  • @KerrekSB - 如果您无法检查操作是否失败并且返回无效,这会更好吗?如果对象已经在寄存器上,则检查将花费一个周期,为更好的安全性付出很小的代价。考虑到引用只不过是一个禁用算术和自动取消引用的指针,为什么不将指针能力镜像为 null 并因此表示无效?引入引用是为了“更容易和更清洁”地使用指针,不是吗?
  • @user2341104:据我所知,这不是添加引用的原因。如果您不再将它们视为真正的指针,而是开始以标准对它们的方式来考虑它们,那么您的论点就不适用了。

标签: c++ reference language-features


【解决方案1】:

动机分为两部分:

1) 引用在概念上是对象的别名,因此它的行为(尽可能和有用)类似于变量名。只要它在范围内,它就指代同一个对象,而且它总是指代一个对象。因此,不可重新安装且不可为空。

2) 发明引用的目的是为了将参数传递给重载的运算符。没有特别需要重新设置这些参数,它们当然必须始终引用一个对象,因为运算符总是有操作数(或者对于一元运算符只有一个操作数)。适合需要的功能是操作数的别名,这就是为什么将引用视为别名的原因。

按照这种方式构思,它们还有其他用途。这些用途中没有一个可以从它们可重新安装或为空中受益,以证明将概念从对象名称中更改出来。最接近的可能是它们在类中用作非静态数据成员。在这种情况下,它们会干扰诸如复制分配之类的事情,但是又不清楚引用数据成员在复制分配时“应该”如何表现,因此没有明确的方法来处理它。指针将处理引用不能处理的情况。

【讨论】:

  • “只要它在范围内,它就引用同一个对象”我注意到这里与现实存在冲突,可以从函数返回引用,并在执行离开范围后继续指向它们的对象的原始对象。向 C++ 添加了引用,以便在不使用指针的情况下通过引用传递更容易和更安全,那么为什么不镜像指针为“null”的能力来表示某些操作是否失败呢?如果有的话会有什么负面影响?
【解决方案2】:
  1. 如果您想引用多个对象,您只需要不同的引用类型。
  2. 如果您希望能够更改引用本身(而不仅仅是它所引用的内容),您需要一个指针。对于可能不引用任何内容(即为空)的引用,同上。

这就是动机:专注于通过其他方式无法完成的事情。

【讨论】:

    【解决方案3】:

    引用不可为空是一件好事,它允许您对函数的输入等做出更强有力的保证。它允许您传递对象而无需进行空指针测试。

    如果您想要一个可变引用,请使用指针或std::reference_wrapper。如果你想要一个可选的返回值,那么你可以使用 boost::optional 之类的东西。

    【讨论】:

    • 更强的保证?悬空引用同样容易产生。如果有的话,可以为空的引用对于验证引用是否有效非常有用,并且检查只需要一个时钟周期。
    【解决方案4】:

    我会说对引用的限制是存在的,因为它允许:

    • 编译器对引用的有效使用进行严格检查,在大多数情况下使用引用时提供编译时安全性
    • 仍然可以使用常规指针完成更复杂的操作

    所以指针适用于您知道您想用它们做一些棘手的事情的情况。参考是典型的“我只想处理一段数据”的典型案例,而不必担心是否正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      • 2018-02-02
      • 1970-01-01
      • 1970-01-01
      • 2014-06-02
      • 2011-03-28
      相关资源
      最近更新 更多