- const限定符用来定义一个常量。试图为常量赋值的行为都将引发错误。
- cosnt对象一旦创建后其值就不能再改变,所以const对象必须初始化。
- 默认情况下const对象仅在文件内有效,如果想让const在文件间共享,在定义时添加extern关键字。
extern const int size = 100;
对const的引用
通过修改绑定的对象可以修改常量引用。
常量引用可以绑定到另外一种类型,在这种情况下引用其实绑定了一个临时量对象,所以对原对象的修改不会反映到引用上。
double i = 12.1;
const int& ir = i;
cout << "value of i: " << i << endl;
cout << "value of ir: " << ir << endl;
cout << endl;
i++;
cout << "value of i: " << i << endl;
cout << "value of ir: " << ir << endl;
/*
value of i: 12.1
value of ir: 12
value of i: 13.1
value of ir: 12
*/
指针和const
指向常量的指针必须也是一个常量指针。
常量指针必须初始化,而且一旦初始化完成,它的值(也就是存放在指针中的地址)就不能再改变了。
变量 ← 指针 ✔
变量 ← 常量指针 ✔
常量 ← 指针 ✖
常量 ← 常量指针 ✔
// 一个指向非常量整数的指针,可以通过修改指针指向的值来修改原对象
int i = 12;
int* const ip = &i;
*ip = 1;
cout << "value of i: " << i << endl;
cout << "value of ip: " << *ip << endl;
/*
value of i: 1
value of ip: 1
*/
// 一个指向常量整数的指针,必须是一个常量指针,并且不允许修改值
const int i1 = 12;
const int* const ip1 = &i1;
顶层和底层const
顶层const表示指针本身是个常量,底层const表示指针所指的对象是一个常量。
int a = 21;
// 顶层const
int* const ap1 = &a;
// 左面的const是底层,右面的是顶层
const int* const ap2 = &a;
// 顶层const
const int b = 42;
// 底层const
const int* bp1 = &b;
int const v2 = 0;
int v1 = v2;
int* p1 = &v1, & r1 = v1;
const int* p2 = &v2, & r2 = v2;
const int* const p3 = &v2, & const r3 = v2;
p1 = p2; //不可以,p2是底层const
p1 = p3; //不可以,p3是底层const
p2 = p1; //可以
p2 = p3; //可以,它们都含有底层const
p3 = p1; //不可以,p3是首先是个常量指针,和底层顶层无关了
p3 = p2; //不可以,p3是首先是个常量指针,和底层顶层无关了
constexpr和常量表达式
- 常量表达式的值在编译时就得到计算
- 在【常量】的语义场景使用constexpr,在【只读】的语义场景使用const
- 指针和引用都可以定义成constexpr,在绑定指针时,constexpr只修饰指针,不修饰指针指向的对象
#include<iostream>
using namespace std;
// 必须定义在函数体外
int i = 10;
int main() {
// 这是一个常量指针,指向整数
constexpr int* p1 = &i;
// 这是一个常量指针,指向整数常量
constexpr const int* p2 = &i;
cout << "value: " << *p1 << endl;
cout << "value: " << *p2 << endl;
}