作用 :定义常量,使变量不可修改,提供编译时类型检查
指针常量(顶层const)与常量指针(底层const):[[4. 易混知识]]
运用场景:
1.常量变量声明:防止意外修改
2.常量指针/引用:保护数据
3.const成员函数:保证不修改对象状态
4.常量对象:整体不可修改
5.常量参数:函数参数保护
作用 :控制变量生命周期和作用域,实现数据共享和封装
静态变量:
void func() {
static int count = 0; // 静态局部变量,只初始化一次
count++; // 每次调用都保持值
cout << count << endl; // 输出累加结果
}
静态函数:
class Example {
static void func() { // 静态成员函数
// 只能访问静态成员
cout << "static function" << endl;
}
};
Example::func(); // 通过类名直接调用
静态成员:
class Example {
private:
static int value; // 静态成员变量声明
static void method(); // 静态成员函数声明
public:
static int getValue() { // 静态成员访问接口
return value;
}
};
int Example::value = 0; // 静态成员变量定义
作用:声明编译期常量、提供编译期计算能力、实现编译期多态、支持模板元编程
// 基本用法
constexpr int MAX = 100; // 编译期常量
constexpr int* ptr = nullptr; // 常量指针
constexpr double PI = 3.14159265359; // 常量表达式
// constexpr函数
constexpr int square(int n) {
return n * n; // 编译期计算
}
constexpr int val = square(5); // 编译期求值
// constexpr类
class Point {
constexpr Point(int x, int y) : _x(x), _y(y) {}
constexpr int getX() const { return _x; }
private:
int _x, _y;
};
注意:函数的返回类型和所有形参类型都是字面值类型,函数体有且只有⼀条return语句(C++11)
在C++14以后,constexpr函数灵活性和功能得到扩展–允许多行语句,包括局部变量、循环和条件分支等操作
功能:当一个变量被volidate关键字修饰时,意味着当我们每次使用这个变量时都会从变量所在的内存中去获取。而不使用编译器为我们优化后保存在cpu寄存器中的备份
作用:防止编译器优化、保证内存访问的准确性、处理硬件访问
// 中断服务程序
volatile int interruptFlag = 0;
// 硬件寄存器
volatile uint32_t* const hwReg = (uint32_t*)0x4000000;
// 多线程变量
volatile bool isRunning = true;
// 组合使用
volatile const int CONFIG = 100; // 易变的常量
作用:声明外部变量、实现跨文件变量共享、管理全局资源、实现C++与C的互操作
// header.h
extern int globalVar; // 变量声明
extern const int CONFIG; // 常量声明
// source1.cpp
int globalVar = 100; // 变量定义
const int CONFIG = 200; // 常量定义
// source2.cpp
#include "header.h"
void func() {
globalVar = 300; // 使用全局变量
}
作用:保证操作的原子性、实现线程安全、避免数据竞争
#include
// 原子变量定义
std::atomic counter(0);
// 原子操作
void threadFunc() {
counter++; // 原子自增
counter.store(100); // 原子存储
int value = counter.load(); // 原子加载
}
作用:防止意外的类型转换
class MyClass {
public:
// 防止隐式转换
explicit MyClass(int x) { } // 只能显式构造
// 不加explicit则允许隐式转换
// MyClass(int x) { } // 允许隐式构造
};
// 使用示例
MyClass obj1(42); // 正确:显式构造
MyClass obj2 = 42; // 错误:不允许隐式转换
// const方式
const int MAX_SIZE = 100; // 有类型检查
const char* MSG = "Error"; // 有作用域
// define方式
#define MAX_SIZE 100 // 简单替换
#define MSG "Error" // 无类型检查
// 区别示例
const int* p1 = &MAX_SIZE; // 正确:有类型信息
int* p2 = &MAX_SIZE; // 错误:const类型检查
// const:运行时可确定
const int size = get_size(); // 运行时初始化
const int arr[size]; // 错误:size不是常量表达式
// constexpr:编译期必须确定
constexpr int size = 10; // 编译期常量
constexpr int arr[size]; // 正确:size是常量表达式
主要区别:
1.处理阶段不同:宏在预处理阶段处理,内联在编译阶段处理
2.类型安全性:宏无类型检查,内联有类型检查
3.调试能力:宏不可调试,内联可以调试
4.作用域:宏无作用域概念,内联遵循正常作用域规则
5.展开方式:宏是简单替换,内联是编译器优化
// 宏定义
#define SQUARE(x) ((x) * (x))
#define MAX(a,b) ((a) > (b) ? (a) : (b))
// 使用示例
int result1 = SQUARE(5); // 展开为: ((5) * (5))
int result2 = SQUARE(a + 1); // 展开为: ((a + 1) * (a + 1)) // 可能有问题
// 内联函数
inline int square(int x) {
return x * x;
}
inline int max(int a, int b) {
return a > b ? a : b;
}
// 使用示例
int result3 = square(5); // 编译器决定是否内联
int result4 = square(a + 1); // 安全且正确
本号文章仅为个人收集总结,强烈欢迎大佬与同好指误或讨论 ^^