关键字const并不能把变量变成常量!在一个符号前加上const限定符只是表示这个符号不能被赋值,也就是它的值对于这个符号来说是只读的,但它并不能防止通过程序内部(甚至外部)的方法来修改这个值。const最有用指出就是用它来限定函数的形参,这样该函数将不会修改实参指针所指的数据,但其他的函数却可能会修改它。
我们都知道const修饰符对所修饰的对象所起的有如下作用:
1、修饰一个对象,也就是常对象或常量,使编译器对该对象实施不能修改的约束
2、修饰类成员函数,也就是常量成员函数,使该成员函数不能修改其所在类的成员变量的值,并且常对象只能访问常成员函数
好处一、提高代码安全性。比如有一个变量a,其存的数值为神舟X号载油量,现要通过它来计算飞船能否顺利到达月球,可是在计算之前,一名程序员不知为什么,可能是因为生活遇上不顺心的事或是工程项目很大写太多代码疲惫了吧,居然在一次操作中把a+10写成了a=10,人为因素,谁能预料呢?结果可想而知,那位程序员就在那里拼命的说,通过程序检测,油还是不够,继续加,最后,不行这飞船的油缸得做大点才行。这时候const修饰符就能起到防灾的作用了,只要把变量a修饰为const。
好处二、提高代码的可读性和可维护性。比如在检查代码逻辑时有一个类,里面有大部分的常成员函数和一些非常成员函数,各成员函数可能修改该类得数据变量,因此要分析该类的功能或这些函数间的联系就不得对每个函数进行不逐一分析了,这时候看到常成员函数便可以跳过因为他不对数据产生改变。又如在维护一段过程性代码时,在分析各语句,各变量间的逻辑关系时,一看到命名有标记为const常量,只要该是数据准确的,就可以减少负担免去对它的分析,因为它是不改变的(一般不会那么无聊通过强制转换改变它吧)。
好处三、提高程序的效率。这主要跟编译器有关,只要知道跟编译器有关即可。查了查资料是这样子的,(1)将某些东西声明为 const 有助于编译器发现使用错误。const 能被用于对象的任何范围,用于函数参数和返回类型,用于整个成员函数。(2)编译器坚持二进制位常量性,但是你应该用概念上的常量性(conceptual constness)来编程。(3)当 const 和 non-const 成员函数具有本质上相同的实现的时候,使用 non-const 版本调用 const 版本可以避免重复代码。
小结:在编程时使用const就要求程序员的思维更加严谨,这就像做人一样为人处事谨慎总有好处的。const修饰符其包含的哲学性,也体现了当今计算机语言的一个魅力点。下面看这段代码:
- #include<stdio.h>
- intmain(void)
- {
- constintlimit=10;
- limit=6;//wrong
- printf("%d/n",limit);
- }
上面的代码明显错误的,但是你继续看下面的代码:
- #include<stdio.h>
- intmain(void)
- {
- intlimit=10;
- constint*limitp=&limit;
- intm=27;
- limitp=&m;
- printf("%d",*limitp);
- return0;
- }
上面的代码可以通过,且值被修改,这说明limitp是一个指向常量整形的指针,这个指针不能用于修改这个整形数,但是任何时候,这个指针本身的值却可以改变。这样,它就指向了不同的地址,对它进行解除引用操作时会得到一个不同的值!
const 常用之处:
1>修饰输入参数
a.对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。
b.对于内部数据类型的输入参数,不要将“值传递”的方式改为“const引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。
2>用const修饰函数的返回值
a.如果给以“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const修饰的同类型指针。
如对于: const char * GetString(void);
如下语句将出现编译错误:
char *str = GetString();//cannot convert from 'const char *' to 'char *';
正确的用法是:
const char *str = GetString();
b.如果函数返回值采用“值传递方式”,由于函数会把返回值复制到外部临时的存储单元中,加const修饰没有任何价值。如不要把函数int GetInt(void) 写成const int GetInt(void)。
3>const成员函数的声明中,const关键字只能放在函数声明的尾部,表示该类成员不修改对象.
说明:
const type m; //修饰m为不可改变
示例:
typedef char * pStr; //新的类型pStr;
char string[4] = "abc";
const char *p1 = string;
p1++; //正确,上边修饰的是*p1,p1可变
const pStr p2 = string;
p2++; //错误,上边修饰的是p2,p2不可变,*p2可变
同理,const修饰指针时用此原则判断就不会混淆了。
const int *value; //*value不可变,value可变
int* const value; //value不可变,*value可变
const (int *) value; //(int *)是一种type,value不可变,*value可变
//逻辑上这样理解,编译不能通过,需要tydef int* NewType;
const int* const value;//*value,value都不可变