有一些值我们不希望他的值发生改变,那么可以用const对其进行修饰。
【资料图】
因为const对象一旦创建就无法修改,因此const对象必须初始化。与改变const对象值无关的操作不会受到影响(例如你可以将eternity赋值给其他数
默认情况下const对象仅在文件内有效,编译器在编译过程中,将用到该对象的地方都替换成对应的值,所以对象的文件必须可以访问到他的初始值,如果不在同一文件的时候,我们无法直接访问这个对象,这样可以避免同一变量的重复定义。在多个文件中重名的const对象其实是在不同文件都独立定义了变量而已。
如果我们想要const对象实现文件的共享,可以使用extern关键字,这样只需一次定义就能在多个文件使用。
const的引用
可以把引用绑定到const对象上,我们称为对常量的引用,同时对常量的引用不能用作修改他所绑定的对象。
因为不允许对常量进行修改,所以我们声明非常量引用去引用常量是无意义的操作,c++规定他是不正确的。
初始化和对const的引用
在引用我们提过,引用类型必须和所引用的对象类型一致,但是有两个例外,第一种例外就是在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换成引用的类型即可。
出现这种情况是因为,编译器为了确保ri绑定一个整型数,会生成一个临时的int型常量用来存放dval的值,然后再将这个常量赋值给ri。
注意:但如果ri是非常量引用,就允许对ri进行赋值,这样会改变ri所引用的对象的值,这时候绑定的对象是一个临时量而不是dval,那么这条语句就失去了意义,因为对临时量操作没有意义,所以c++视为非法定义。
对const的引用可能引用一个非const的对象
常量引用r2绑定i是合法的,即使i不是常量,但是通过r2修改i是非法的,但是可以通过其他的途径修改i的值从而修改r2。
指针和const
指针也可以和const进行组合,指向指针的常量不能用于改变其所指对象的值。想存放常量对象的地址,必须用常量指针。
指针中我们提到,指针的类型必须和所指对象的类型一致,但是也有两个例外,第一种就是指允许令一个指向常量的指针指向非常量对象。
和常量的引用一样,指向常量的指针仅仅是不呢通过该指针来改变对象的值,而该对象可以随意改变。
const 指针
指针是一个对象,所以可以把指针定义为常量,同时常量指针必须初始化,而且初始化后他的值不能改变,把*放在const关键字之前来说明他是一个常量指针,同时说明不能变的是指针的值而不是指向那个对象的值
我们说过了解一个对象的含义,可以从右向左一次阅读,所以curErr首先是一个常量,然后是一个指针,所以他是一个常量指针,同时它指向int对象,pip同理可以推断。
指针是一个常量意味着他不能改变所指的对象,但不意味着他不能通过指针修改对象的值,这完全取决于所指对象的类型,例如pip是一个指向常量的常量指针,所以pip既不能改变所指的对象,也不能改变所指对象的值,但是curErr指向一个非常量整数,那么可以通过curErr修改errNumb的值。(第一次可能有些难以理解但是通过对上面代码的验证,你应该会有所收获。。
顶层const
我们用顶层const表示指针本身是个常量,用底层const表示指针所指的对象是一个常量
更一般的顶层const可以表示任意的对象是常量,这一点对任何数据类型都适用,底层const则与指针和引用等复合类型的基本类型部分有关。
执行对象的拷贝操作时,常量是顶层const还是底层const区别明显,其中顶层const不受什么影响。
底层const的限制不能忽视,当执行对象的拷贝操作时,拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的类型可以相互转换(非常量可以转换成常量,反之不行)。
p3绑定的是一个常量,那么我们不能把p3去初始化p,因为p是一个非常量。其他的还是相对来说比较好理解的。