C++ 面试高频细碎知识点,笔试选择题、口头高频追问重灾区。知识点零散、极易混淆,全部采用标准化面试话术,直接背诵,规避扣分点。
本章必考考点:const、static、volatile、inline、extern、typedef/using、explicit、friend、noexcept、auto&decltype
1. const 全场景用法
1.1 核心作用
const 用于修饰数据,限定只读属性,禁止被二次修改;提升代码安全性,辅助编译器优化,属于编译期常量约束。
1.2 五大使用场景(必背)
- 修饰普通变量:定义只读变量,初始化后无法修改;区别于宏常量,const 常量具备类型、作用域、支持语法检查。
- 修饰指针 (必考口诀:左定值、右定址)
const int* p常量指针:指针指向的值不可改,指针地址可改;int* const p指针常量:指针地址不可改,指向的值可改;const int* const p:地址、数值全部只读。
- 修饰函数形参 :防止函数内部意外修改实参,保护入参数据;大型对象推荐
const 引用传递,兼顾安全与效率。 - 修饰函数返回值:限制返回值不可被修改,杜绝外部误写返回数据,多用于自定义类返回场景。
- 修饰类成员函数 :函数内部禁止修改类普通成员变量 ,且只能调用 const 成员函数;const 成员函数默认第一个隐含 this 为
const 类类型*。
1.3 高频追问
问 :const 成员函数如何修改成员变量?
答 :使用mutable关键字修饰对应成员变量,打破 const 只读限制,常用来定义计数器、缓存标记。
问 :#define 和 const 的区别?
答:define 预处理纯文本替换,无类型、无作用域、无语法校验;const 是类型常量,编译期校验、支持作用域、安全性更高。
2. static 关键字(局部 / 全局 / 类成员)
2.1 底层共性
被 static 修饰的变量 / 函数,统一存储在全局静态区,生命周期贯穿整个程序,作用域被强制缩小。
2.2 四大应用场景(满分背诵)
- 修饰局部变量:变量仅初始化一次,生命周期随程序,跨函数调用保留上次数值;作用域仍局限于当前函数内部。
- 修饰全局变量 :普通全局变量跨文件可见;static 全局变量仅限当前源文件可见,隔离作用域,解决多文件命名冲突。
- 修饰普通全局函数:函数仅当前文件可调用,外部文件无法链接访问,实现函数私有化封装。
- 修饰类成员(静态成员)
- 静态成员变量:不属于对象、属于类,所有对象共享一份,需类外初始化;
- 静态成员函数:无 this 指针,只能访问静态成员变量/静态函数,无法访问普通成员。
2.3 面试禁忌
静态成员函数不能加 const 修饰;const 修饰成员函数本质修饰 this 指针,静态函数无 this 指针。
3. volatile 作用与使用场景
3.1 核心定义
volatile 是易变关键字 ,禁止编译器做读写优化,强制每次操作数据都直接从原始内存读取,不从 CPU 寄存器缓存读取。
3.2 解决的问题
编译器默认会做数据缓存优化,频繁访问的变量会存入寄存器,减少内存 IO;多线程、硬件寄存器场景下,缓存数据和内存数据不一致,引发逻辑 BUG。
3.3 三大适用场景
- 多线程并发:多个线程同时读写共享变量,保证线程实时读取内存最新值;
- 嵌入式开发:直接操作硬件寄存器,硬件数据会自主变化,禁止缓存;
- 信号处理器:异步信号修改全局变量,防止优化导致数据读取失效。
3.4 面试易错点
volatile不保证线程安全,仅禁止读写优化;无法替代锁,不能解决并发竞争问题。
4. inline 内联函数优缺点
4.1 底层原理
inline 为编译期优化策略,编译器将内联函数的函数体,直接嵌入调用位置,省去函数压栈、跳转、返回的开销。
4.2 优点
- 消除函数调用开销,提升短小函数执行效率;
- 相比宏定义,具备类型检查、作用域、语法校验,安全性更高;
- 支持类内封装,兼顾性能与代码整洁度。
4.3 缺点
- 冗余代码膨胀:多处调用内联函数,会重复拷贝代码,增大可执行文件体积;
- 调试难度增加:无独立函数调用栈,断点调试不方便;
- 编译器自主权:inline 只是建议,编译器可自主拒绝内联。
4.4 适用与禁用
- 适合:代码行数少(1-5 行)、高频调用的简单函数;
- 禁止:递归函数、包含循环/分支、代码量大的复杂函数。
4.5 inline 与宏区别
宏是预处理文本替换,无类型检查;inline 属于真正函数,支持参数校验、返回值、作用域约束。
5. extern 用法与跨文件引用
5.1 核心作用
extern 关键字用于声明外部标识符,告知编译器:变量/函数定义在其他源文件中,仅做声明、不分配内存。
5.2 两大使用方式
- extern 修饰变量/函数(C/C++ 通用)
- 声明外部全局变量/全局函数,实现跨文件访问;
- 区分:声明不分配内存,定义才分配内存。
- extern "C"(高频面试)
- 作用:让 C++ 编译器以C 语言规则编译指定代码;
- 底层原理:禁止 C++ 名字重整,解决 C/C++ 混合编程链接失败问题;
- 应用场景:调用第三方 C 库、底层 SDK、操作系统接口。
5.3 面试踩分点
extern int a:声明变量;int a:定义变量;工程禁止重复定义,允许多次声明。
6. typedef 与 using 区别
6.1 基础功能
二者作用一致:为已有数据类型起别名,简化复杂类型书写。
6.2 核心区别(5 点必背)
- 语法风格:typedef 旧式语法;using 新式语法,直观易懂;
- 定义指针:typedef 易产生歧义;using 语义统一,无歧义;
- 模板支持 :typedef不支持类型别名模板;using 原生支持模板别名,C++11 专属;
- 函数类型:using 定义函数类型别名更简洁;typedef 写法繁琐;
- 兼容性:typedef 兼容 C 语言;using 仅 C++11 及以上支持。
6.3 总结
简单类型二者均可;涉及模板、复杂类型,优先使用 using,是现代 C++ 标准写法。
7. explicit 关键字作用
7.1 产生背景
C++ 默认支持隐式类型转换:单参构造函数,会自动接收普通数据并隐式构造对象,极易引发隐性 BUG。
7.2 核心作用
修饰单参构造函数 ,禁止编译器进行隐式类型转换,仅允许显式手动构造对象,规避隐式转换带来的未知问题。
7.3 代码直白理解
- 无 explicit:
A a = 10;合法,编译器自动隐式构造; - 有 explicit:
A a = 10;非法,只能写A a(10)显式构造。
7.4 工程规范
所有单参数构造函数,建议全部加 explicit,杜绝隐性类型转换。
8. friend 友元函数 / 友元类
8.1 核心定义
friend 为突破访问权限的关键字,授权外部函数/外部类,直接访问本类私有、保护成员。
8.2 两种形式
- 友元函数:可为全局友元函数、类成员友元函数;被授权后,可无视访问权限,直接读取类私有成员。
- 友元类
friend class B;B 类所有成员函数,都可以访问当前类的私有成员。
8.3 三大特性
- 友元关系单向:A 声明 B 为友元,B 可访问 A,A 无法自动访问 B;
- 友元关系不传递:A 友元 B、B 友元 C,C 不等于 A 的友元;
- 友元不能继承:父类友元,无法作用于派生类。
8.4 优缺点
优点:简化跨类操作、减少冗余接口(运算符重载高频使用);
缺点:破坏面向对象封装性,工程中尽量少用。
9. noexcept 关键字
9.1 C++11 新增关键字,核心作用
指定函数不会抛出异常,辅助编译器优化代码,减少异常捕获开销。
9.2 两种使用方式
- 简单声明 :
void func() noexcept,声明函数禁止抛异常; - 条件异常 :
void func() noexcept(flag),布尔表达式控制是否支持异常。
9.3 底层机制
若 noexcept 修饰的函数强行抛出异常,程序直接调用std::terminate终止程序,而非触发 try-catch。
9.4 高频使用场景
移动构造、移动赋值、STL 容器、底层工具类;告知容器当前操作无异常,容器可启用高性能移动逻辑。
9.5 面试追问
问 :noexcept 和 throw () 区别?
答:throw () 仅做编译期提示;noexcept 参与类型推导,且能触发编译器深度优化,是 C++11 替代 throw 的新标准。
10. C++11 auto/decltype 推导规则
10.1 auto 关键字
核心作用
编译期自动推导变量数据类型,简化复杂类型(迭代器、模板)书写。
四大推导规则(面试必考)
- 普通 auto:自动剔除顶层 const、引用属性;
- auto&:保留 const 与引用属性,禁止临时变量绑定;
- auto&&:万能引用,既能接收左值、也能接收右值;
- 初始化不能为空,auto 必须依托初始值推导类型。
10.2 decltype 关键字
核心作用
不定义变量,单独推导表达式的数据类型,多用于模板编程。
三大推导规则
- 普通变量:推导变量原生类型,包含 const、引用;
- 表达式:根据表达式运算结果推导类型;
- 加括号
decltype((x)):强制推导为引用类型。
10.3 auto 与 decltype 联合用法
decltype(auto):完美转发,完整保留原值的 const、引用属性,模板编程高频使用。
🔥 本章综合高频追问
-
问 :volatile 能不能和 const 一起使用?
答 :可以,
const volatile修饰变量代表:变量只读、且数据易变,常见于嵌入式硬件只读寄存器。 -
问 :内联函数和普通函数调用有什么区别?
答:普通函数存在调用开销;内联函数编译期嵌入代码,无调用开销,但会造成代码膨胀。
-
问 :友元破坏封装,为什么还要用?
答:特殊场景简化代码,如二元运算符重载、跨类数据交互,权衡便利性与封装性。
-
问 :auto 为什么不能用于函数形参?
答:C++11 不支持,C++14 之后支持;早期 auto 仅用于变量类型推导。
📝 模块总结
本模块全部为 C++ 细碎易混关键字,是笔试选择题、面试官随口追问的高频题库。核心考察:权限修饰、内存生命周期、编译优化、类型推导、跨文件编译。全部吃透,彻底解决面试零散冷门知识点扣分问题。
