const大家都知道,当我们希望定义一种变量,它的值不能被改变时使用。
一 初始化时注意几点
1.定义时必须初始化
const int i = 42;//correct const int k;//wrong,const should be initialized
2.可以用非常量初始化
int i = 42; const int j = i;//正确,拷贝完成后j的值与i没什么关系了
3.默认情况下仅在文件内有效
如果多个文件声明了同名const变量,编译器认为是不同的变量。若要在多个文件中使用同一个const,需要在声明和定义时,均添加extern关键字,这样只需要定义一次就可以了。
二 const的引用
对const的引用虽然简称为“常量引用”,引用对象是常量还是非常量只是可以决定其所能参与的操作,却不会影响到绑定关系本身。事实上,c++语言不允许随意改变引用绑定的变量,所以又可以理解为所有引用都是常量引用(引用关系为常)。
引用对象可以是个非常量,常量引用仅仅对引用可参与的操作做出限定,例如:
int i = 42; const int &r2 = i; r2 = 0;//错误,不能通过r2改变i
所谓常量的指针或引用,不过是指针或引用自身认为指向了常量,因此”自觉地”不去改变所指对象的值。
三 const指针
常量指针必须初始化,且初始化后,值不能再改变了。
int errNumb=0; int *const curErr=&errNumb;
四 顶层与底层
顶层const:指针本身为常量 (不能改变值)
底层const:指针所指对象为常量 (可以改变值)
int i = 0; int *const p1 = &i;//不能改变p1的值,是顶层const const int ci =42;//不能改变ci的值,这也是个顶层const const int *p2 =&ci;//可以改变p2的值,这是个底层const
非常量可以转为为常量,反之不行。
五 constexpr和常量表达式
c++11规定:允许将变量声明为constexpr类型以便编译期验证变量的值是否是一个常量表达式
constexpr int sz=size();
在上述例子中,只有当size()是一个constexpr函数时,这条声音语句才正确。
常量表达式:值不会变,且在编译过程中就能得到计算结果的表达式。
const int sz = function();//sz不是常量表达式,尽管sz本身为一个常量,但fucntion()值无法在编译阶段获取
const与constexpr区别在于:
1.const未区分编译期常量和运行期常量,constexpr限定编译期常量。
2.constexpr声明中如果定义了指针,constexpr也只对指针有效,对所指对象无效。即constexpr只能顶层。
const int *p=0;//p是指向常量的指针 constexpr int *p1 =0;//p1是指向整数的常量指针
六 auto与const
auto会忽略顶层const,保留底层const。
const int ci=i; auto b = ci;//b是一个整数,ci的顶层const属性被忽略 auto e= &ci;//e是一个指向整数常量的指针,因为对常量取地址是一种底层const