C++const详解

const限定符

当我们需要一个变量它的值不能被改变时,我们可以用关键词const对变量的类型加以限定。这时此const类型只能执行不改变其内容的操作

初始化

由于const对象一旦被创建后就能不能被改变,所以const对象必须初始化。

const int i=sizeof(int); // 正确
const int j=1; // 正确
const int m; // 错误,必须初始化

编译时,编译器将会在用到该变量的地方都替换成对应的值。默认情况下,const对象被设定为仅在文件内有效。当需要在多个文件中使用这个const对象时,需要加上extern限定符

const引用

当把一个引用绑定到const对象上时,不能修改它所绑定的对象,称为对常量的引用。同时,const类型的对象只能被const引用绑定。

const int a=9;
const int &b=a; // 正确
b=1; // 错误,const引用不能修改绑定的对象的值
int &c=a; // 错误,const对象只能被const引用绑定

引用类型中的例外

引用的类型必须与其所引用对象的类型一致,但在初始化常量引用时,允许用任意表达式作为初始值

double val=1.5;
const int &re=val; // 正确

此时该表达式的值会转换成引用的类型,在编译过程中,编译器会产生一个临时的对象让re绑定:

double val=1.5;
const int temp=val;
const int &re=temp;

允许这样做的原因是:当re不是常量时,表示人们想要对val进行修改。然而这个修改只能改变temp,而无法改变val。这个行为时无效的,因此被归为非法行为。

const引用对非const对象的引用

const引用只对修改做出了限定,并未对被引用的对象本身做出限定。因此被引用的对象也可以为一个变量。同时,该变量的值修改了,const引用的值也会被修改。

int a=0;
const int &b=a; // 正确,初始化允许常量引用时允许用任意表达式作为初始值
a=1; // 正确,此时b的值为1

const指针

指针是对象而引用不是,因此可以把指针本身定为常量。同样的,常量指针必须初始化。需要清楚的一点是:常量指针不能改变的值是指针的值而不是指针指向的地址的值。通常,我们把*放在const关键字以前说明该指针是一个const指针。这样隐含着一个信息:不变的是指针而不是指针指向的值。

int a=9;
int *const p1=&a; // 正确
int b=1;
p1=&b; // 错误,p1将会永远指向a
*p1=1; // 正确,p1指向的值a是可以改变的
const int c=10;
const int *const p2=&c; // 正确,表示一个指向常量的常量指针
*p2=1; // 错误,p2是一个指向常量的指针
int *p3=&c; // 错误,只有const指针才能指向const类型的变量

不同位置的const含义判断

判断的依据是从右向左阅读,如下:

const int a=1;
const int b=0;
const int *p1=&a; // 正确,表示p1指向的是一个const int类型的值
const int *const p2=&b; // 正确,表示p1是一个const指针,指向的是一个const int类型的值
p1=&b; // 正确,因为p1不是const指针,它只是指向一个const int类型的值
p2=&a; // 错误,因为p2是一个const指针,所以它的值不能被改变

顶层const和底层const

在这里,我们使用顶层const表示指针本身是一个常量;使用底层const表示指针所指的对象是一个常量。

推广以后,顶层const表示任意的对象是常量;底层const则表示指针和引用等复合类型的基本类型部分有关。

const和宏的区别

  • 编译器处理:define在预处理的时候展开;const在编译中替换
  • 类型和安全检查:define没有类型,仅作展开;const有具体类型,编译时会做类型检查
  • 存储方式:define仅作展开,不分配内存;const会在内存中分配内存

注意点

  • const对象必须初始化
  • const对象仅在该文件中有效
  • const成员变量不能在声明是初始化
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值