C++ const之旅

const对象一旦创建后其值就不能再改变,因此const对象必须初始化。

const的引用

对常量的引用不能被用作修改它所绑定的对象,因此要用const声明引用:
const  int  m=10;

int  &r1=m;  //错误:r是对常量的引用

const  int  &r2=m;  //正确,引用及其对象都是常量

const  int  &r3=42;  //正确,r3是一个常量引用

当一个常量引用被绑定到另外一种类型上时:

int  dval=3;

const  int  &ri=dval;

ri=5;  //错误,因为ri是一个常量引用,不能通过ri更改dval的值

scanf("%d",&r);  //正确,&r拿到的是变量dval的地址,相当于是对&dval操作

指针和const

要想存放常量对象的地址,只能使用指向常量的指针:

const  double  pi = 3.14;   //pi是个常量,它的值不能改变

double  *ptr = π  //错误,ptr是一个普通指针

const  double  *cptr = π  //正确,cptr可以指向一个双精度常量

*cptr = 42.312;  //错误,不能给*cptr赋值

一个指向常量的指针可以指向一个非常量对象:

double  dval = 3.14159;   //dval是一个双精度浮点变量,它的值可以改变

cptr = &dval;  //正确,但是不能通过cptr改变dval的值,即*cptr=5.159错误。但是scanf("%d",cptr);正确,因为cptr拿到的是dval的地址,相当于是对&dval操作


指针是对象而引用不是,因此可以像其他对象类型一样,允许把指针本身定义为常量。常量指针必须初始化,而且一旦初始化完成,则它的值(也就是存放在指针中的那个地址)就不能再改变了。

把*放在const之前用以说明指针是一个常量,这样的书写形式隐含着一层意味:即不变的是指针本身的值而非指向的那个值。

例如:

int  errNumb = 0;

int  *const  curErr = &errNumb;  //curErr将一直指向errNumb

const  double  pi = 3.14159;

const  double  *const  pip = pi;  //pip是一个指向常量对象的常量指针

要想弄清楚上述这些声明的含义最行之有效的办法是从右往左阅读。上述例子中,离curErr curErr最近的事const,意味着curErr本身是一个常量对象,对象的类型由声明符的其余部分确定,声明符的下一个符号是*,意思是curErr是一个常量指针,最后,该声明语句的基本数据类型部分确定了常量指针指向的是一个int对象。同理,pip也是一个常量指针,并且该指针指向的对象pi也是一个常量。

指针本身是一个常量并不意味着不能通过指针修改其所指对象的值,能否这样做完全依赖于所指对象的类型。因此curErr永远指向errNumb对象,不能更改,但是可以更改errNumb对象的值,即可通过*curErr=10更改errNumb对象的值;而pip因为指向的对象是一个常量,因此不能通过指针pip修改pi的值。

顶层const

如前所述,指针本身是一个对象,他又可以指向另外一个对象。因此,指针本身是不是常量以及指针所指的是不是一个常量就是两个相互独立的问题。用名词顶层const表示指针本身是个常量,而用名词底层const表示指针所指的对象是一个常量更一般的,顶层const可以表示任意的对象是常量,这一点对任何数据类型对适用,而底层const则与指针和引用等复合类型的基本类型部分有关。比较特殊的是,指针类型既可以是顶层const也可以是底层const,这一点和其他类型相比区别明显:

int  i = 0;

int  *const  p1 = &i;  //不能改变p1的值,顶层const

const  int  ci = 42;  //不能改变ci的值,顶层const

const  int  *p2 = &ci;  //不能用p2改变ci的值,但能改变p2所指的对象,即能让p2指向另一个int型常量对象,底层const

const  int  *const  p3 = p2;  //靠右的是一个顶层const,靠左的是底层const。该例既不能改变p3,也不能改变p3所指对象

const  int  &r = ci;  //用于声明引用的const都是底层const

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值