目录
概述
- 对象的类型决定了其上的操作.
- 只能在const类型的对象上执行不改变其内容的操作.
- const对象必须初始化,初始值可以是任意表达式.
// const放在两个位置都可以
// const对象必须初始化
const int ci1 = 10;
int const ci2 = 20;
int i = 5;
const int ci = i;
// 用一个const对象初始化另外一个对象
int j = ci;
const引用(reference to const)
严格来讲应该叫做对const的引用,因为引用不是一个对象,不能让引用本身为const.
- 引用不是对象
- const引用所绑定的对象可以是const,也可以是非const
- 如果const引用绑定的是非const对象,我们不能通过const引用来修改对象的值,但是可以通过绑定到该对象的其他的非const引用来修改。
int i = 100;
const int ci = 200;
const int& r1 = i;
const int& r2 = ci;
int& r3 = i;
int& r4 = ci; // wrong
r1 = 300; // wrong
r3 = 300; // right
引用的类型必须与其所引用对象的类型一致,但是有两个例外。1. 如上述const 引用可以绑定非const对象 2. const引用初始化时可以是不同类型
const int& r1 = 100; // right
const int& r2 = r1 * 200; // right
double dv = 3.14;
const int& ci = dv;
// right这里实际进行了两步
// 1. int tmp = dv; 2.const int& ci = tmp;
int& ci2 = dv; // wrong,可能对临时对象进行更改
指向常量的指针(pointer to const)
-
const对象的地址只能用指向const的指针来存放
-
指向const的指针可以存放非const对象的地址
-
这段关系是const的,不可以通过该途径修改所指对象的值,但是可以通过其他途径修改。
// 两种形式都可以
const int* ptr1; // 常见
int const* ptr2;
int* ptr3;
int i = 1024;
int j = 2048;
ptr1 = &i;
ptr2 = &i;
ptr3 = &i;
*ptr1 = 1025; // 不可以
*ptr2 = 1025; // 不可以
*ptr3 = 1025; // 可以
ptr1 = &j; // 可以
ptr2 = &j; // 可以
常量指针(const pointer)
- 指针中存放的地址不可以改变,但可以通过该指针改变所指对象的值。
- 常量指针必须初始化。
int i = 10;
int *const pi = &i; //pi
*pi = 20;
std::cout << "i=" << i << endl; // i is 20 now
顶层const和底层const(top-level const and low-level const)
- 指针类型既可以是顶层const,也可以是底层const.顶层const是说指针本身是常量,参照常量指针的讲解;底层cosnt是指指针所指对象为常量。
- 顶层const对任何数据类型都适用
int i = 10;
int *const pi0 = &i; // 顶层const
const int ci0 = 100; // 顶层const
int const ci1 = 200; // 顶层const
const int* pi1; // 底层const
int const* pi2; // 底层const
常量表达式和constexpr变量
表达式(expression)的概念:
一个表达式由一个或多个运算对象和一个运算符组成,一个表达式产生一个结果。字面值和变量是最简单的表达式,其结果就是其值。
常量表达式(const expression)是指值不会改变并且在编译阶段就能得到结果的表达式,包括:1. 字面值 2. 用常量表达式初始化的const对象。一个对象(表达式)是不是常量表达式,既要看数据类型也要看初始值。
const int i0 = 20; // i0是常量表达式
int i1 = 25; // i1不是常量表达式
const int i_plus = i + 1; // i_plus是常量表达式
const 成员变量
- const和static搭配使用,可以只分配一份内存.
- 必须初始化,声明时初始化或者定义时初始化.
const 成员函数
- 常量对象,常量对象的引用,常量对象的指针都只能调用常量成员函数。
- const成员函数只能调用const成员函数.
- const成员函数中不可以修改成员变量,如果想修改,使用mutable修饰成员变量.
mutable
即使在const成员函数中,也可以修改成员变量。
总结
- 尽可能地使用const
- 为减少代码重复, 可以使用non-const 成员函数调用const成员函数