卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 基础与语法

  • 面向对象

  • STL 与容器

  • 内存管理

  • C++11 与现代 C++

    • C++11中的新特性有哪些
    • C++11中的多线程编程
    • 左值引用和右值引用的区别
      • 简要回答
      • 详细回答
      • 适用场景
      • 代码示例
      • 知识拓展
    • 移动语义有什么作用,原理是什么
    • 完美转发的作用及实现
    • 说一下c++中stdmove与stdforward的区别
    • 说一下lambda函数
    • 仿函数与lambda性能对比
    • c++中 STL中仿函数与lambda表达式的性能对比
    • C++中的RAII机制
    • C++中的异常处理机制
    • C++中的协程概念及实现
  • 智能指针

  • 并发与 I/O

# 左值引用和右值引用的区别

# 简要回答

左值引用(T&)绑定到左值(有持久身份的对象),右值引用(T&&)绑定到右值(临时对象或将要销毁的对象)。

右值引用是实现移动语义和完美转发的关键。

简单点说:左值引用给已经存在的变量起了个别名,右值引用专门“捡漏”临时变量的引用,能让资源“偷”过来用而不拷贝,提高效率。

# 详细回答

  • 左值引用(T&):

必须绑定到左值(有名称、有内存地址的对象)

生命周期必须长于引用本身,传统C++中唯一的引用类型

常用于函数参数传递以避免拷贝

  • 右值引用(T&&):

只能绑定到右值(临时对象、字面量、将亡值)

C++11引入的新特性,主要用途是实现移动语义和完美转发

可以修改所引用的右值(与const左值引用不同)

  • 总结:

左值引用只能绑定到实实在在的变量,右值引用专捡临时变量和快要消失的值的"便宜"。

# 适用场景

  • 左值引用适用场景:

函数参数传递(避免拷贝)

函数返回多个值(通过引用参数)

操作符重载(如operator<<)

  • 右值引用适用场景:

移动构造函数/移动赋值运算符

标准库容器元素插入(如vector::push_back)

工厂函数返回大型对象

完美转发(std::forward)

# 代码示例

#include <iostream>
#include <utility>  // for std::move
#include <vector>

void process(int& lref) {
    std::cout << "处理左值: " << lref << "\n";
}

void process(int&& rref) {
    std::cout << "处理右值: " << rref << "\n";
}

class BigObject {
public:
    BigObject() { std::cout << "构造\n"; }
    BigObject(const BigObject&) { std::cout << "拷贝构造\n"; }
    BigObject(BigObject&&) noexcept { std::cout << "移动构造\n"; }
};

int main() {
    // 1. 左值引用示例
    int x = 10;
    int& lref = x;  // 正确:左值引用绑定左值
    process(x);     // 调用左值版本

    // 2. 右值引用示例
    process(20);            // 调用右值版本
    int&& rref = 30;        // 右值引用绑定右值
    process(std::move(x));  // 转为右值引用

    // 3. 移动语义示例
    std::vector<BigObject> v;
    BigObject obj;
    v.push_back(obj);          // 调用拷贝构造
    v.push_back(BigObject());  // 调用移动构造
    v.push_back(std::move(obj)); // 调用移动构造

    // 4. 引用折叠示例
    auto&& universal = x;  // 最终类型是int&
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

# 知识拓展

  • 拓展

    1.引用折叠规则:

T& & → T&

T& && → T&

T&& & → T&

T&& && → T&&

2.万能引用(Universal Reference):

模板参数T&&或auto&&可能是左值引用或右值引用

根据实参类型决定最终类型

配合std::forward实现完美转发

3.std::move本质:

无条件将左值转为右值引用

不移动任何东西,只是类型转换

表示对象可以被移动

  • 知识图解

image

  • 面试官可能追问

Q1.什么情况下右值引用会绑定到左值?

使用std::move将左值显式转换为右值引用时

函数返回的局部变量作为右值时

被移动后的对象(处于有效但未指定状态)

Q2.为什么移动构造函数要加noexcept?

标准库容器在重新分配内存时,如果移动操作可能抛出异常,则会选择拷贝而非移动

保证异常安全性

提高代码效率(允许某些优化)

Q3.万能引用和右值引用有什么区别?

万能引用是模板推导上下文中的T&&或auto&&

右值引用是具体类型的X&&

万能引用可以根据实参推导为左值引用或右值引用

Last Updated: 3/10/2026, 6:08:48 PM

← C++11中的多线程编程 移动语义有什么作用,原理是什么 →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪