const关键字

Const关键字

关键点1:全局const变量分配在全局区,只读,不能修改

关键点2:程序内const变量分配在栈区,只读,但是可以通过指针修改

关键点3:编译阶段会发生常量折叠,把出现const变量的地方替换掉

 

Const关键字的总结

声明常变量:

 

对这里的代码,声明了常变量a,为其分配了内存,分配在栈内存区,a是只读的,所以第二行不能修改

但是,可以用一个指针,指到a的内存,然后修改值,实际是已经修改了,但是编译的时候常量折叠替换了。

然后声明的变量b,赋值为a,按道理应该是2,然而并不是,从汇编来看,这里发生常量折叠,类似宏替换,在编译阶段已经把a替换为5,所以这里b还是5,不同于宏替换,常量折叠依然会分配内存。

 

全局的const变量,分配内存在常量区(全局区)

Const与extern的话,因为const只能在声明的时候初始化一次,

 

 

这个样子声明以后,其他部分引用extern const int a=0,会编译错误,提示已经定义过

改为这个样子,其他部分引用,不初始化即可。

Const与指针

Const与指针相关有两种,一种是指向常量的指针,另一种是指针常量

前者指向常量的指针(也称底层const),意为,指向常量,指向内容不能改,但是指针可以改,声明的时候

Const int a;

Const int *p;

P=&a;

这个样子没问题

这个样子也没问题,

P可以赋值,但是不能改p里面的内容

后者,指针常量(也称顶层const),一个不能改变指向的指针,由于const优先向左结合,左没有的时候向右结合

声明就是

这个是没问题的,但是,如果要改p1的指向就会有问题

 

常引用const int &

通常做形参,在函数里不能改变值,我的理解一方面是不在函数里改变值,另一方面是可以增加程序可读性,知道参数是做什么的,以及另外一种调用函数的时候能处理const实参和非const实参(同时对两种进行匹配),例如会出现insert(1,2),add(3,4),Fun(“122”),这种,const变量传进去,进行类型匹配(根据C++Prime6版P262,P270,类型为const引用的形参一个属性是,代入的实参与形参不符合但能转为引用时,程序可以生成正确类型的临时变量,使用转换后的实参初始化它,再传入函数,所以应该注意,需要修改的变量或类引用传递的时候,不加const)。另外还有const int ,无意义,因为这种形参生成一个临时的副本变量,随后会销毁

常量指针做参数,也是进行相应的类型匹配

 

*Const变量在程序内声明,会在栈内生成,

https://blog.csdn.net/hzh2007/article/details/12006855

我的测试是,在函数内声明的const变量c,可以通过用指针修改const变量内存的值,然而修改之后,编译器依然发生了常量折叠,并且,下面可以看到,声明的全局const变量a不能通过这种方式改变,编译器会报错,因为a是全局的,地址在全局区。

 

Const修饰函数返回值

1.返回const引用,这种旨在提高效率,返回类的对象需要调用复制构造函数,而返回引用则不会,但是要注意的是,必须返回的是const类型的(一种可以是传入的const引用,另一种在函数里声明const类型的变量返回(局部变量),或者返回一个const值  ),并且不要返回局部变量或者对象的引用(会在函数调用完后释放或者调用析构函数),

2.返回const对象,这种情况发生在重载+的情况,如果返回不是const对象,将会可以赋值例如a+b=c,或者手误if(a+b==c)写为if(a+b=c),编译器不能发现错误,这不是我们想要的,所以+重载应该返回const对象(重载+形参为const,所以必须生成一个新的类对象返回);并且相关的,由于C++从左向右读输出语句(cout<<a)<<b,所以这里cout<<a必须是ostream的引用;相关的a=b=c,赋值b给a,(a=b)=c,a=b这个必须是可以赋值的对象,所以可以用返回对象或者返回对象引用,建议返回对象引用避免调用复制构造函数提高效率。

 

 

这些是合法的。,常量引用a返回的容易理解,就是返回a的引用,而另外的c则是,在函数调用期间,在区声明c,然后函数结束后,释放栈区内存,所以与普通的函数也没太大区别,但是编译的时候依然被常量折叠

所以其实在函数内声明的const变量也是在栈内,只是在函数内只读。

 

Const修饰类的成员函数

这个在C++Prime看动态分配内存的时候见到一个const,比较奇怪,查了一下发现的,

 

有主要两点,1是const关键字的类方法不能改变类的属性,否则不能编译通过

2,const的类实例,只能调用const的方法,例如这个

Const A lalal;

Lalal.Hello()是可以的

这种情况下,函数重载,普通的类对象会优先调用hello no const,但是只存在const函数的时候也可以调用。

hello调用的是非const函数,而hello1调用的是const的函数

我们加入一个非const方法,const的对象调用会报错

 

 

普通的对象则调用不出错

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值