目录
一,修饰变量
1.1,修饰指针(顶层const和底层const)
int a = 1;
int* const b = &a; // 常量指针,const修饰的是b,b保存的是一个地址,所以b的值不能修改;但是b地址指向的变量值可以修改。
const int* c = &a; // 指针常量,const修饰的是*c,而不是c,所以指针c指向的变量(*c)不可修改;但是指针c的值可以修改。
一般建议如下书写:
int a = 1;
const int* const b = &a;
1.2,修饰普通变量
int const a = 1;
1.3,修饰静态变量
static const int a = 1; // 一般出现在全局变量或者类的成员对象场景中
1.4,修饰引用
引用特性:
引用只能在声明时候进行初始化,不可分开,一旦引用被初始化为一个对象,就不能被指向到另一个对象。
1.4.1 修饰左值引用
int const a = 1;
const int& b = a; // 当引用的值有const修饰时,引用必须加上const修饰
注意:
A,作为局部变量加const,只能确保const修改的对象不能修改
int a = 1;
const int& b = a;
a = 3; //正确, b指向的值还是可以被修改
const int& 有点类似常量指针,只能保证指针保存的地址值是一个常量,但是该地址指向的值可以被改变
B,加const修饰可以绑定到右值上
int a = 2;
const int& b = a * 22; // 编译通过
int& c = a * 22; // 编译失败 a * 22 是一个右值
C,作为函数入参加const可以防止被修改
void Func(const T& t);
用const来修饰,可以保证对象 t 的值不会被修改
1.4.2 修饰右值引用
cosnt int&& a = 3; // 3是将亡值,右值分为 将亡值和纯右值。const修饰无实际意义。
二,修饰函数
2.1 修饰函数返回值
const void Func(); // 无实际意义
const T Func(); // 返回的是一个常量,需要 const T t = Func();
const T& Func(); // 返回的是一个常量左值引用,注意不能返回右值(编译失败),不能返回局部对象(运行出错)
cosnt T&& Func(); // 返回的是一个常量右值引用,注意不能返回左值(编译失败),只能返回右值
T* const Func() // 返回的是一个常量指针
const T* Func(); // 返回的是一个指针常量
2.2 修饰函数形参
形参又分为入参和出参,在函数内计算的值会保存在出参中。
void Func(const T t); // 形参t 和实参会发生一次拷贝构造函数,无法通过 t 修改 t 对象的值,无实际意义
void Func(const T& t); // 防止函数修改实参的值
void Func(const T&& t); // 右值传递,减少对象构造析构成本
void Func(const T* t); // 防止函数修改指针指向的值
2.3 放置函数尾部修饰
前提场景:Func是类的成员函数
void Func() const; // 表面不会修改类的数据成员,准确地说应该是非静态数据成员
作用:
A,表明该成员函数不会修改数据成员。
B,常量(即 const)对象可以调用 const 成员函数,而不能调用非const修饰的函数。
三, const和其他关键词
3.1 const和constexpr
简单而言,const其实是readonly,constexpr才是const。其他介绍链接。
3.2 const和mutable
在C++中,mutable也是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中。
作用:可以测试const成员函数被调用次数。
3.3 const和volatile
PS:mutable和volatile的差异,前者用于修饰类的非静态成员变量,在const成员函数中可以修改类的该变量。volatile主要用多线程编程,告知编译器对某个变量不要进行优化处理,每次都需要从内存中获取该变量的值。介绍链接
四,const_cast
去除const的修饰作用 ,介绍链接