const是C++中定义只读变量的唯一标准方式,编译期禁止赋值,必须声明时初始化;与#define和constexpr语义不同;指针/引用组合时只读性由const位置决定;全局const默认内部链接。

const 修饰的变量就是只读变量
在 C++ 中,const 是定义只读变量的唯一标准方式。它不是“运行时不可改”,而是编译期就禁止赋值操作——一旦声明为 const,任何试图通过该变量名修改值的代码都会被编译器直接报错。
常见误操作:用 #define 或 constexpr 替代 const 变量来“模拟只读”,但语义和行为完全不同:
-
#define PI 3.14是文本替换,不占内存、无类型、无法取地址,且可能被意外宏展开污染 -
constexpr int x = 42;要求必须是编译期常量,适用场景更窄(比如数组长度),但比const更严格 - 普通
const变量可以是运行时初始化(如从函数返回值、用户输入读取),只要之后不改就行
const 变量必须初始化,否则编译失败
const 变量没有默认值,声明即必须初始化,否则 g++ 和 clang++ 都会报 error: uninitialized const variable。
实操建议:
- 在声明处直接赋值:
const int max_size = read_config(); - 若依赖构造逻辑,优先用
const成员变量 + 构造函数初始化列表(类内) - 避免写成两步:
const int x; x = 10;—— 这是非法的,第二行就会报错
const 与指针/引用组合时,只读性位置很关键
只读对象、只读指针、只读指向的内容,三者由 const 的位置决定,容易混淆出错。
典型写法与含义:
-
const int* p;或int const* p;:指针可变,所指内容不可改(“只读数据”) -
int* const p = &x;:指针本身不可变(不能指向别处),但内容可改 -
const int* const p = &x;:指针和内容都只读
错误现象:把 const int* p 当成“p 不可变”,结果给 p++ 编译通过但语义错;或传参时把非 const 指针赋给 const int* 参数(合法),反过来却不行(类型不匹配)。
全局 const 变量默认内部链接,头文件中要小心
在 C++ 中,const 全局变量默认具有 internal linkage(类似加了 static),这意味着:如果在头文件里写 const int version = 1; 并被多个 .cpp 包含,每个编译单元都会生成一份副本,不违反 ODR(One Definition Rule)。
但这也带来隐患:
- 调试时看到多个同名变量,地址不同,容易误判为 bug
- 若真需要跨文件共享同一份只读变量,必须显式加
extern声明 + 单一定义:
/* header.h */ extern const int global_flag; <p>/<em> impl.cpp </em>/ const int global_flag = 42;</p>
不加 extern 就别指望它在别的文件里能取到地址或用于模板非类型参数(除非是字面量类型且 constexpr)。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











