C++ 关键字与特性详解
一、const 与 constexpr
1. const
- 作用:定义运行时常量,防止意外修改
- 应用场景:
- 特点: 运行期确定值可用于任何作用域必须初始化
2. constexpr (C++11)
- 作用:定义编译期常量表达式
- 应用场景:
- 特点: 编译期求值C++14放宽了对函数体的限制比const更严格的编译期检查
二、static 关键字
1. 静态局部变量
void counter() { static int count = 0; // 只初始化一次 ++count; cout << count << endl; }
- 特点:函数调用间保持值,存储在静态存储区
2. 静态成员
class MyClass { static int s_count; // 静态成员变量 public: static void print() { // 静态成员函数 cout << s_count; } }; int MyClass::s_count = 0; // 类外初始化
- 特点: 类所有实例共享静态函数只能访问静态成员没有this指针
3. 静态全局变量/函数
- 限制作用域在当前文件
- 避免命名冲突
三、volatile 关键字
1. 基本用法
volatile int flag = 0; // 告诉编译器不要优化
2. 使用场景
- 硬件寄存器访问
- 多线程共享变量
- 信号处理程序中的变量
3. 与const结合
const volatile int READ_ONLY_REGISTER = 0x1234;
- 既不能被程序修改,又可能被外部改变
四、mutable 关键字
1. 使用场景
class Cache { mutable bool dirty; // 可在const函数中修改 public: int getValue() const { dirty = true; // 允许修改 return value; } };
2. 典型应用
- 缓存标志
- 互斥锁成员
- 调试计数
五、explicit 关键字
1. 作用
禁止隐式类型转换
2. 应用示例
class String { explicit String(int size); // 禁止 int->String 隐式转换 }; String s1(10); // OK String s2 = 10; // 错误 String s3 = 'a'; // 错误
3. 使用建议
- 所有单参数构造函数都应考虑使用
- 避免意外的类型转换
六、inline 关键字
1. 基本用法
inline int max(int a, int b) { return a > b ? a : b; }
2. 现代C++中的变化
- 类内定义的成员函数默认inline
- 链接时不产生多重定义错误
- 编译器最终决定是否内联
3. 使用注意事项
- 适合短小频繁调用的函数
- 递归函数和虚函数通常不会被内联
- 过度使用可能导致代码膨胀
七、现代C++新增关键字
1. auto (C++11)
auto i = 42; // int auto& r = i; // int& auto&& rr = i; // int& auto list = {1, 2, 3}; // std::initializer_list<int>
2. decltype (C++11)
int x = 0; decltype(x) y = 1; // y的类型是int decltype(auto) z = y; // 保留引用和const
3. override/final (C++11)
class Base { virtual void foo() final; // 禁止重写 }; class Derived : public Base { void foo() override; // 显式重写 };
4. noexcept (C++11)
void func() noexcept; // 保证不抛出异常 void func() noexcept(true); // 条件性noexcept
八、关键字的组合使用
1. const + volatile
const volatile int hardware_register;
2. static + constexpr
static constexpr int MAX = 100;
3. inline + constexpr (C++17)
inline constexpr double pi = 3.1415926;
4. mutable + lambda
auto func = [x = 0]() mutable { return ++x; };
九、面试常见问题
- const和constexpr的主要区别是什么?const是运行时常量,constexpr是编译期常量
- 什么情况下必须使用mutable?需要在const成员函数中修改的成员变量
- 为什么推荐构造函数使用explicit?避免意外的隐式类型转换导致的bug
- static成员变量为什么需要在类外定义?需要分配存储空间,避免多重定义
- volatile在嵌入式开发中的作用?确保编译器不对硬件寄存器访问进行优化
- 现代C++中auto的使用场景?复杂类型声明、模板代码、lambda表达式等
- override关键字的作用?显式表明重写虚函数,增加代码可读性,编译器检查重写是否正确