语言基础

13 篇文章

查看专题概览 / 复习建议

核心问题

  • 什么是左值、右值、将亡值
  • 移动语义和拷贝语义分别解决什么问题
  • constconstexprconsteval 的边界在哪里
  • constinit 解决了什么初始化问题
  • autodecltype(auto) 在推导上有什么差异
  • 指针、引用和 nullptr 的语义边界是什么
  • static 在局部变量、全局变量、类成员里的作用分别是什么
  • 作用域、存储期、链接属性分别是什么,它们之间如何区分
  • C++ 常见函数传参方式有哪些,分别适合什么场景
  • 四种类型转换各自适合什么场景
  • 隐式转换为什么容易引入问题,explicit 解决什么问题
  • 函数重载、默认参数、返回值推导有哪些规则
  • lambda 的捕获列表和闭包对象该怎么理解
  • 直接初始化、拷贝初始化、列表初始化有什么差异

建议复习顺序

  1. 值类别与引用(左值右值与移动语义)
  2. 指针、引用与 nullptr
  3. 常量表达式(const与constexpr)
  4. 类型推导(auto与decltype)
  5. 初始化方式(初始化与列表初始化)
  6. static 关键字
  7. 作用域、存储期与链接属性
  8. 常量求值边界(constinit与consteval)
  9. 函数传参方式与适用场景
  10. 类型转换
  11. 隐式转换与 explicit
  12. 函数规则(函数重载默认参数与返回值推导)
  13. lambda 与捕获

子主题导航

高频追问

  • 为什么右值引用能实现移动而不是拷贝
  • std::move 到底有没有移动对象
  • const 成员函数和顶层 const 有什么区别
  • auto 会不会保留引用和 const
  • nullptr 为什么优于 NULL
  • static 成员变量为什么要类外定义
  • 内部链接、外部链接和无链接分别是什么意思
  • constexprconstevalconstinit 应该怎么选
  • 值传递、const T&T&& 应该怎么选
  • dynamic_cast 为什么有运行时开销
  • 单参数构造函数为什么容易触发隐式转换
  • 默认参数为什么建议只写在声明处
  • lambda 捕获引用时为什么容易出生命周期问题

易错点

  • std::move 误认为”真的移动”
  • 混淆右值引用和万能引用
  • 认为 constexpr 一定在编译期求值
  • 把作用域、存储期、链接属性混成一个概念
  • 把“为了性能”机械地全部改成引用传参
  • 把引用和指针当成只是”语法不同”
  • static 的几种语义混成一类
  • 滥用 reinterpret_cast
  • 忽略隐式转换带来的歧义和意外构造
  • 只会写 lambda,不理解捕获和闭包对象

学习策略

记忆技巧

值类别三兄弟

  • 左值(lvalue) = 有名字、可取地址、持久存在
  • 右值(prvalue) = 临时对象、即将销毁、可以移动
  • 将亡值(xvalue) = 资源可被转移的对象

类型推导口诀

  • auto = “去掉顶层的const和引用”
  • decltype(x) = “如果是变量名,就是声明类型”
  • decltype((x)) = “如果是表达式,看表达式的值类别”

static三层含义

  • 局部static = “函数内常驻变量”
  • 全局static = “文件内私有函数/变量”
  • 类static = “类级别的共享数据”

练习建议

  1. 基础概念:先掌握每个主题的核心概念和典型示例
  2. 代码分析:通过分析代码加深对概念的理解
  3. 动手实践:自己编写代码实现各种特性
  4. 错题总结:记录易错点,形成自己的知识库

关联学习

这些主题之间有很强的关联性,建议按照复习顺序逐个学习,并注意:

  1. 理解每个概念的底层原理而不仅是语法
  2. 掌握典型代码示例和常见陷阱
  3. 学会在实际项目中正确应用这些特性
  4. 特别注意生命周期相关的风险