const使用及问题总结
一、背景
最近在论坛中回答了一个别人提出的关于const的问题,就随着自己的理解答复了,不久就有朋友引用贴子说我说的有问题。于是乎自己思索思索、翻翻书发现自己理解的确实有问题。好记性不如烂键盘,何况记性不好,为了加深理解以及以后查询,今天就好好总结一下。
二、const对象
1、定义const对象
定义一个变量代表一个常数的方法存在一个问题:可能被有意或无意的修改。const限定符提供了一个解决办法,他把一个对象转换成一个常量。const int bufsize = 512;
定义bufsize常量并初始化为512.变量bufsize仍然是一个左值,但是这个左值是不可修改的。 因为常量定义后就不能修改,所以定义时必须初始化。
注意:非const变量默认为extern,要使const变量能够在其他的文件中访问,必须显示的指定它为extern(定义和声明的地方都要extern)。
2、const引用
const引用是指向const对象的引用。可以读取但是不能修改refVal,因此不能通过使用refVal来修改ival。const int ival = 1024; const int & refVal = ival;//正确 int &ref2 = ival;//错误,将const对象绑定到非const引用
const对象可以初始化为不同类型的对象或者初始化为右值。同样的初始化对于非const引用却是不合法的。观察将引用绑定到不同类型时所发生的事情,最能理解上述内容:int & r = 42;//错误, const int & x = 42;//正确
编译器会把这些代码转换成如下形式的编码:double dval = 3.14; const int & ri = dval;
如果ri不是const,那么可以给ri赋一个新值。这样不会修改dval,而是修改了temp。期望对ri的赋值来修改dval的程序员会发现dval并没有修改。仅允许const引用绑定到需要临时变量作为媒介来完全绑定过程的值,因为const引用是只读的。int temp = dval;//创建一个临时变量,将double类型转换成int类型 const int & ri = temp;//将ri绑定到这个临时变量
非const引用只能绑定到与该引用同类型的对象。const引用则可以绑定到不同但相关的类型的对象或绑定到右值。
3、指针和const限定符
3.1指向const对象的指针
如果指针指向const对象,则不允许用指针来改变所指的const值。因此就出现了指向const对象的指针。这里的cptr是一个指向double类型const对象的指针, const限定了cptr指针所指向的对象类型,而非cptr本身。也就是说,cptr本身并不是const。在定义时不需要对它进行初始化,如果需要的话,允许给cptr重新赋值,使它指向另一个const对象。但不能修改其所指对象的值:const double *cptr;
*cptr = 42;//错误,*cptr是const的
不能使用void*保存const对象的地址,必须使用const void*类型的指针保存const对象的地址。
可以修改const指针所指向的值,即:给这个指针赋值是合法的,而修改指针所指向的对象的内容是非法的。3.2const指针
除了指向const对象的指针外,c++还提供了const指针--- -指针本身的值不能修改。从右向左读:“curErr是指向int类型对象的const指针”。与其它const量一样,const指针的值不能修改,这就意味着不能使currErr指向其它对象,但是可以改变它所指向的对象的值。任何给const指针赋值的行为都会导致编译错误, 因此const指针必须在定义时初始化。int errNumb = 0; int * const curErr = &errNumb;
4、从const成员函数返回*this
在普通的非const成员函数中,this的类型是一个指向类类型的const指针。可以改变this所指向的值,但不能改变this所保存的地址。在const成员函数中,this的类型是一个指向const类类型对象的const指针。既不能改变this所指向的值,也不能改变this所保存的地址。const成员函数写法:这时const是写在成员函数后面的。这时的this就既不能改变this所指向的值,也不能改变this所保存的地址。void X::func() <span style="color:#ff0000;">const</span>