C++中的常量(一) const限定符

最近在重新看<<C++ Primer>>,第一遍的时候const和constexpr看得并不太懂,这次又有了些更新的理解,当然可能仍然有许多不对的地方...

首先,const限定符即“常量”,一旦使用了const,那么对象的值不能再改变,比如:

  const int i=1;

同时,const修饰的变量必须初始化,因为如果不初始化,那么就永远无法初始化了。

常量的初始化并不一定需要用常量,字面值或者是普通对象都是可以的,例如:

  int i=5;

  const int j=i;

const最难理解的是用于指针和引用,以及函数输入参数的类型、类成员函数。

首先对于指针类型,主要有这两种:

  1.const int* p1=&i;//指向常量的指针

  2.int* const p2=&i;//常量指针

对于指针类型的常量的解读,可以从变量开始,由内到外。(1)中,const修饰的是int* p1,也就是说,p1是一个指向整型的指针,同时p1所指向的对象的值是不能通过p1来改变的,但是可以改变p1指向的对象,因此说p1是指向常量的指针。例如:

  (1)*p1=5;//错误,不能通过指针修改对象

  (2)p1=&j;//正确,p1指向的对象可以改变

对于(2),可以看到const是直接修饰指针p2的,也就是说,p2的值是常量,但是可以通过p2修改对象的值,所以称为常量指针,例如:

  (1)*p2=5;//正确,可以通过p2修改对象的值

  (2)p2=&j;//错误,p2不能修改

另外需要注意的是,所谓的不能通过p来修改对象,或者p不能修改,仅是对于p来说。对象i的值还是可以通过其他渠道进行修改的。

 

引入两个概念:顶层const和底层const。可以简单的认为,声明或者定义的对象(指针也是对象),如果对象本身是const的,那么就是顶层const,否则是底层const。从概念上并不容易搞清除,看几个例子:

  (1)const int i=1;//i本身是const,顶层

  (2)const int* p=&i;//p本身不是常量,底层

  (3)int* const p=&i;//p本身是常量,顶层

  (4)const int* const p=&i;//左边是底层,右边是顶层

 

对于常量引用,同样有两种:

  (1)const int& a=i;//正确,i不需要是常量

  (2)int& const b=i;//同样正确,不过意思不同

对于(1),和指针一样,不能通过a修改i的值,不过对于(2),其实等价于int& b=i。原因在于,顶层const被忽略掉了。

 

对于函数的参数类型,例如:

  int foo(const int& t);

  int foo(int& t);//错误,重复声明

按照函数重载的规则,以上两者只能存在一个,建议采用const版本。一部分原因,在于变量在传输的时候,会忽略顶层const的属性,而非常量可以转换为常量。另外,这样定义的适用性更强。

还有一种情况,就是类成员函数的const,例如:

  struct base

  {

    int num;

    int getNum()  const{return num;}//若没有const,那么对于const base将无法使用该函数

  };

这样的const,作用是把类对象的this指针转换为常量。在不需要修改对象成员的时候,可以保证成员不被修改,另外,与上一种相同,当对象为常量对象时,只有这样才能正确返回。

另外,const可能还有许多应用,这里先说这些,遇到再补充。另外,C++11 新加入了constexpr,下篇文章将会介绍。

posted @ 2017-08-25 21:32  luStar  阅读(547)  评论(2编辑  收藏  举报