1.使用const应该注意:
- const修饰的变量不能改变
- const必须初始化
- 用一个对象初始化另外一个对象,则它们是不是const都无关紧要。
1 int i = 42;
2 const int ci = i;
3 int j = ci;
2.常量的引用
- 常量(被const修饰的变量)必须绑定在常量的引用上
1 const int ci = 1024;
2 const int& r1 = ci;
3 int& r2 = ci;//错误试图让一个非常量的引用绑定一个常量对象
3.顶层const和底层const
顶层const和底层const用来判断拷贝(赋值或者传参)时是否合法的
顶层const可以表示任意的对象是常量(指针、引用、int、double都可以)
只有指针和引用等复合类型可以是底层const
(1)怎么判断底层const还是顶层const
1.通过形式:
const和变量中间没有“&”或者“*”它就是一个顶层const,否则就是底层const
2.通过定义(针对指针)
如果这个指针值不能变(指向的地址不能改变),那么它就是一个顶层const;如果一个指针所指向的是一个常量那么就是底层const。
1 const int a=10; 2 int* b=&a;//错误,&a相当于指向a的指针,指向常量的指针是一个底层const,右边有底层const左边没有,错误
(2)当执行对象(表示两边都是对象,所以引用不满足)的拷贝赋值时,常量是顶层const还是底层const区别明显,其中顶层const不受什么影响。这句话应改为当当执行对象的拷贝赋值时,常量是顶层const还是底层const区别明显,顶层const可以删除(也就是顶层const不作为等号右边的值是否可以赋值给等号左边值的判别标准),底层const必须一致(也就是底层const在等号两边必须同时出现,或则都不出现),使用时先把顶层const删除,再判断。(注意是上述准则不满足才用)如果以上准则不满足接下来再用非常量可以转换成常量这个准则来判断(拷贝的时候右边的类型必须往左边的类型转换,如果右边是一个常量左边是一个非常量这样就会导致常量向非常量转换,这样是不可以的)
1 int i=0; 2 const int ci=42; 3 const int* p2=&ci; 4 //首先&i可以理解为一个指向i的指针(int *),虽然等号左边有底层const右边没有,但是非常量(int *)可以转换成(const int *),从而使等号右边带有底层const 5 p2=&i;
(3)关于引用的几个结论
对于5举个例子:
1 int i=0; 2 const int& j=10; 3 i = j;//正确
首先根据 4去掉&,就变成int i=const int j,这个时候没有&就可以用顶层const了,也就是去掉const变成int i=int j;(注意这个地方不能先用常量不能转换成非常量来判断),注意等号右边往等号左边的转换。再注意一点:上述方法不能用于引用,引用的初始化就用const int&可以接任何东西,int&只能接int。
————————————————————————————————————————————————————————
个人认为在初始化一个变量的时候用顶层const不受影响(也就是可以删除),然后用常量不可以转换成非常量,非常量可以转换成常量来判断。
1 int i=10; 2 const int ci=20; 3 int*const p2=&ci;//错误,int*const p2相当于int*p2,相当于&const int*,&const int*不能转换成int* 4 const int*const p3=&i;//正确,const int*const p3可以写成const int* p3,&i相当于int*,则int*可以转换成const int* int*p=p3;//错误,const int*const p3可以写成const int* p3,则const int*不可以转换成int*
如果是赋值的话(也就是等号右边的变量已经被初始化,已经有一个值了),就用顶层const的值不可以改变,底层const的值可以被改变,但指向的之不能改变来判断
1 int i=10; 2 int j=20; 3 const int ci = 42; 4 const int* p2 = &ci; 5 const int* const p3 = p2; 6 int* const p4=&i; 7 //*p2 = *p3;//错误,p2指向的值不可以改变 8 p2 = p3;//正确p2的值可以被改变,也就是p2指向的值可以被改变 9 //p4=j;//错误,p4是顶层const其值不可以改变,原来已经指向i了就不能再指向j 10 11 int a=0; 12 const int& b=10; 13 a=b;//a的值可以被改变,它可以被认为是一个底层const,因此正确