引用

编程语言 / reference

本地源文件:docs/lang__reference.md

引用

声明具名变量为引用,即既存对象或函数的别名.

引用可以看成是 C++ 封装的非空指针,可以用来传递它所指向的对象,在声明时必须指向对象.

引用不是对象,因此不存在引用的数组、无法获取引用的指针,也不存在引用的引用.

引用类型不属于对象类型

如果想让引用能完成一般的复制、赋值等操作,比如作为容器元素,则需要 reference_wrapper,通常维护一个非空指针实现.

引用主要分为两种,左值引用和右值引用.

左值和右值

对左值和右值的讲解,请参考 值类别 页面.

左值引用 T&

通常我们会接触到的引用为左值引用,即绑定到左值的引用,同时 const 限定的左值引用可以绑定右值.以下是来自 参考手册 的一段示例代码.

---|---

左值引用最常用的地方是函数参数,用于避免不需要的拷贝.

---|---

右值引用 T&&(C++ 11)

右值引用是绑定到右值的引用,用于移动对象,也可以用于 延长临时对象生存期

---|---

## 悬垂引用

当引用指代的对象已经销毁,引用就会变成悬垂引用,访问悬垂引用这是一种未定义行为,可能会导致程序崩溃.

以下为常见的悬垂引用的例子:

  * 引用局部变量

---|---

  • 解分配导致的悬垂引用
---|---

  * 内存重分配导致的悬垂引用

---|---

类似 std::vectorstd::unordered_map 等容器的插入操作,均有可能导致内存重新分配.

使用引用时,应时刻关注引用指向的对象的生命周期,避免造成悬垂引用.

通常静态检查工具和良好的代码习惯能让我们避免悬垂引用的问题.

引用相关的优化技巧

消除非轻量对象入参的拷贝开销

常见的 非轻量对象 有:

  • 容器 vectorarraymap
  • string
  • 其他实现了或继承了自定义拷贝构造、移动构造等特殊函数的类型

而对 轻量对象 使用引用不能带来任何好处,引用类型作为参数的空间占用大小,甚至可能会比类型本身还大.

这可能会带来些的性能负担,同时可能会阻止编译器优化.

以下属于 轻量对象

  • 基本类型 intfloat
  • 较小的 聚合体类型
  • 标准库容器的迭代器

将左值转换为右值

使用 std::move 转移 对象的所有权.这通常见于局部变量之间,或参数与局部变量之间:

---|---

但不是所有时候都需要这么做,比如 [函数返回值优化](../value-category/#常见误区).

### 右值延长临时量生命期

从语义上,临时量可能会带来的额外的复制或移动,尽管多数情况下编译器能通过 [复制消除](../value-category/#复制消除) 进行优化,但引用能强制编译器不进行这些多余操作,避免不确定性.

## 参考内容

  1. [C++ 语言文档——引用声明](https://zh.cppreference.com/w/cpp/language/reference)
  2. [C++ 语言文档——值类别](https://zh.cppreference.com/w/cpp/language/value_category)
  3. [Does const ref lvalue to non-const func return value specifically reduce copies?](https://stackoverflow.com/questions/38909228/does-const-ref-lvalue-to-non-const-func-return-value-specifically-reduce-copies)

* * *

> __本页面最近更新: 2026/1/7 08:56:54,[更新历史](https://github.com/OI-wiki/OI-wiki/commits/master/docs/lang/reference.md)
>  __发现错误?想一起完善?[在 GitHub 上编辑此页!](https://oi-wiki.org/edit-landing/?ref=/lang/reference.md "edit.link.title")
>  __本页面贡献者:[cmpute](https://github.com/cmpute), [Ir1d](https://github.com/Ir1d), [CoderOJ](https://github.com/CoderOJ), [ksyx](https://github.com/ksyx), [Tiphereth-A](https://github.com/Tiphereth-A), [Xeonacid](https://github.com/Xeonacid), [c0nstexpr](https://github.com/c0nstexpr), [Duodenum87](https://github.com/Duodenum87), [Enter-tainer](https://github.com/Enter-tainer), [mgt](mailto:i@margatroid.xyz), [ouuan](https://github.com/ouuan)
>  __本页面的全部内容在**[CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/deed.zh) 和 [SATA](https://github.com/zTrix/sata-license)** 协议之条款下提供,附加条款亦可能应用