刚学c++的时候只知道const是用来定义常量的,比如:
const int MAX =5;
//在功能上等同于#defineMAX 5
int array[MAX];
这样做的好处是可以把一个看不出任何差别的常量给它起一个一目了然的名字。其他人或自己日后再看到的时候就不会糊涂为什么这里凭空出现一个1,那里莫名其妙有一个3。合理的给常量起名字可以提高代码的可读性和可维护性。有一天我们需要修改大量同值同类型的常量(如果你非要这么做的话)就可以很简单的把定义改一下就好,而不用在所有代码中一处一处的找(你也不用担心有没有漏掉的)。
使用const修饰符还可以预防在程序中偶然的修改那些我禁止修改的变量,比如:
const int index= 512;
//…do something
If(index = 1)//哦,报错了- -#
//…do something
So,看到了const的好处了吧,它帮我们找到了一处因大意而写错的地方:==才是等于操作符。这里还有一个窍门,就是在每一个判断语句中把常量都写在左边:
if(1 == index)//这个就保险了。。。
//do something
本以为const不过如此,可是突然间我发现了这么三行代码,我就凌乱了:
Const int *p1 ;
Int * const p2 ;
Const int *const p3;
这,不一样吗?开始我曾这样问,后来才知道,这个真不一样。p1是一个可以修改它所指向的对象却不可以修改其指向对象的值。也就是说它可以指向一个常量,也可以不这样做,而int*p4则不能指向常量只能指向常量。p2是一个可以修改它所指向对象的值却不可以修改它所指向的对象,比如:
Int *p2 = &a;//只能这样初始化
P2 = &c;//又出错了- -#
*p2 = 4;//正确
p3是p1,p2的交集,它不能修改指向的对象,也不能修改指向对象的值。
会了上述的问题后,我很长一段时间里没有被const打扰,直到某年某月某日看到了它在函数中的应用:
Void fun1(const char *);
Void fun2(constchar&);
Cons int* fun3();
这三个没的说,跟上面道理一样。
int exClass::fun4()const;
这一个是类中的成员函数特有的用法,在定义类对象的时候,我们可能会定义一个常量类对象:
Const exClassexc;//exClass是一个已经定义的类类型。
于是编译器就会区分那些成员函数是会修改成员数据的,哪些成员函数是安全的不修改成员数据的。所以,只有被const修饰的成员函数才能被常量类对象调用:
class exClass{
public:
char get()const {return c;}
void set(char cf){c=cf;}
//…………..
pravite:char c;
//…………..};
Const exClassexc;
Exc.get();//可以
Exc.set(‘#‘);//出错啦- -!
但是,我们这样做也是错误的:
class exClass{
public:
char get()const {return c;}
void set(char c f)const {c=cf;}//出错啦- -!!!
//……………
pravite:char c;
//…………..};
把一个修改类数据成员的函数声明成const是非法的,它跟const表达的意思不相符,这是候会收到一个编译时刻错误:error:cannot modifu a data member within a const member function.
当然,如果非要改一个const类对象的数据成员也不是不可能,只是要做额外的工作:把类数据成员定义成:mutable。