(4)常见的对const的误解
在学习const的用法时,要留意几种常见的误解,对初学者来说更是这样。
①误解一:用const修饰的变量的值一定是不能改变的。在一些特殊情况下,可能需要临时改变一下常变量的值,而且这也是做得到的。下面来看一个例子。
1. #include<iostream>
2.
3. void ConstTest1()
4. {
5. const int a = 5;
6. int *p;
7. p = const_cast<int*>(&a); //强制类型转化,将&a赋给p,强制类型转化为整型指针,去掉const性质。
8. (*p)++;
9. std::cout<<a<<std::endl;
10. }
11. void ConstTest2()
12. {
13. int i;
14. std::cout<<"please input an integer:";
15. std::cin>>i; // 相当于 int i=8;
16. const int a = i;
17. int &r = const_cast<int&>(a);//强制类型转化,将a赋给&r,强制类型转化为引用,去掉const性质。
18.
19. r++;
20. std::cout<<a<<std::endl;
21. }
22.
23. int main()
24. {
25. ConstTest1();
26. ConstTest2();
27. return 0;
28. }
复制代码
执行程序,并从键盘输入8,程序的输出结果为:
5
please input an integer: 8
9
在函数ConstTest1()中输出5,并不表明常变量a的值没有改变,而是编译器在优化代码时将a替换成了文字常量5。实际上a的值已经变成了6。在函数ConstTest2()中,由于常变量a无法转化成对应的文字常量,所以它显示出被修改后的值。如果在函数ConstTest1()中的(*p)++;语句前加个断点,单步执行,就会发现执行这条语句后,a的值由5变成了6。
另外,无论是ConstTest1()还是ConstTest2()中,只要不是直接写const int a = 5;间接输入的情况下,如写成中间过渡形式,int i=5,const int a=i;之后在输出a时会变为6;值发生改变。
②误解二:常引用或常指针,只能指向常变量。这是一个极大的误解。引用被声明为常引用(或指针被声明为指向常量的指针),这是说明不能通过该引用(或该指针)去修改被引用对象(或被指向单元)的值。至于被引用对象原来是什么性质,或者是否会被其他引用修改,是无法由常引用(或常指针)来决定的。看下面这个小例子。
1. #include<iostream>
2.
3. int main()
4. {
5. int i = 5;
6. const int &ri = i;
7. std::cout<<ri<<std::endl;
8. int *p = &i;
9. *p = 6;
10. std::cout<<ri<<std::endl;
11. return 0;
12. }
复制代码
程序的运行结果是:
5
6
在程序中,虽然ri被定义为常引用,但这只是规定了不能通过ri来修改i的值,但并没有阻止通过其他的引用、指针修改i的值,甚至直接写i=6也是没有问题的。所以,要理解C++设立常引用(常指针)的用意,主要是保证在一个函数体内部,不应变化的变量不被意外修改,从而提高程序的健壮性。