C++中CONST的深入浅出——三步走

小序  

 今天无聊,写一点自己对c++CONST的理解,具体方法呢,还是按照三步走:是什么,为什么,怎么样。我相信大多数老程序猿都有着自己的思维方式,小风就比较习惯这种老套的方式。闲话就不多说了,开始正题。

1.CONST是什么?

作为c++中关键字之一的const,起作用如下:

     1.内容上:其修饰的变量、函数、指针都为只读形式,即修饰的部分无法再去修改其值或是内容,具体实现后面会再说。很多教材都说成常量,这样并不利于你理解,应该理解为值无法修改的变量本质上还是一个变量,只是权限上有所限制,但若是通关其他方法获取其地址(例如堆栈中的const变量,因为有地址所以还是可以被修改)

     2.作用时间上:const是程序在编译时起作用,作用是检查是否有操作修改了被const修饰的变量,若有则编译出错。

2.为什么使用CONST?

     有的时候,我们希望定义一种变量,而它的值不能被改变。比如:当我们使用一个变量来表示缓冲区大小,使用变量的好处是当变量的大小不适合时,我们可以很方便的修改这个值,但是却也要十分小心的去检测这个值是否被程序一不小心的改变了,为了实现这一点,可以用CONST对其加以限定。

const int bufSize = 521;  //缓冲区大小为521
bufSize = 1024;           //编译错误:试图向const对象拷贝数据;

     简单的说就是在编译时可以提醒程序猿,是否有一些不能改变的值被程序不小心修改了,也就是大家常说的增加了代码的强健性。

3.怎么样使用CONST?

     使用const可修饰的地方主要有4个:成员变量、成员函数、函数的形参、函数的返回值。我们来一个一个干掉。

①const修饰成员变量

     

int a1=2;   //这是一个普通变量,并且被初始化 


1.  const int a2=2;    //常量数据

    若是后面有程序想改变其值,则会出现编译出错,(const在编译时起作用),当然也有一些奇淫巧技可以改变他的值(题外话),比如:

2.   int *p = (int*)&a2;
    *p = 5;
    cout<<a2<endl;    //此时a2值则改变了,因为堆栈上的变量有地址,可以通过获取地址来找到内容并修改,而const的意思是无法通过a2直接修改
                      //如果变量为static const a2,那以上的方法也无法修改,因为它的存储内存在静态区,此内存为只读,无法修改。


3.   int * a3 = &a1;   //一个很平常的指针,把上面a1的地址传了过来


4.   const int * a4 = &a1;    //指针指向的对象为常量,而指针本身并不是。
                                          //可理解为右值&a1不能变,左值可a4可以变。(术语:底层const)


5.   int * const a5 = &a1;  //和上面的正好相反,理解为可理解为右值&a1能变,左值a5不可以变.(术语:顶层const)



6.   int const * const a6 = &a1;   //左右两值均为常量
7.   const int * const a7 = &a1;   //同上,左右两值均为常量。此两种表达方式效果一样

②const修饰成员函数

当const关键字去修饰一个函数时,那么在这个函数中,任何的成员变量都不能修改,否则报错,我们用手来举个栗子:

class  A                     //我们先来声明一个类,名字叫A
{
public:                      //Public继承了以下两个函数
	void B();            //这货就是一个普通的函数
	void C() const;	     //这货被const修饰了,就是我们要说的被const修饰的函数,继续往下看
private:
	int aa,bb;           //这里声明两个私有变量,即private继承了两个变量aa和bb
};
void A::B()                  //我们开始定义那个普通的函数B
	{

		aa=5;        //在函数中,我们修改了私有变量aa的值,此时不会报错,因为啊,这个B太普通了。
	} 

	
void A::C()const
	{
	
	       aa=5;        //在这个函数C中 ,我们又企图去修改,那么这个时候不好意思了。aa是A的成员变量,const修饰的函数是不允许在函数中修改的,
                            //所以这个时候,编译的时候就会提示你:哎呀!我们不能这样做,犯法的呀。


       //   int aa=5;     //现在这个aa可以修改了,为啥呢?因为啊~现在的aa不已经是上面那个aa了,已经不是成员变量了,只是一个刚刚
                           //声明的int类型的变量
至于为啥名字可以一样啊?因为他们作用域不同,不同的作用域是允许有相同变量名字的。}

还有一点比较重要的就是:const函数只能调用const函数,脑袋里过一下。

其次:const的位置一定是要在函数的后面,不能再前面,这点一定要记住。


③const修饰函数返回值

当const去修饰一个函数的返回值时,表示这个值不能够被修改,及返回一个常变量,具体方法如下

const int * fun(){   //const data,non-const pointer
 2     int *a=new int(2); //在堆上声明并定义一个值为2的int值,(声明是给编译器看的,定义是实际参与编译的,作用是提高编译效率。)
 3     return a;   
 4 }

④const修饰修饰形参

当const去修饰形参的时候,指此形参不能为左值,即不能修改:

void fun1(const int x) {
     x=5;   ///编译出错,因为x被const修饰,不能再函数体内被修改。
}

关于const的用法就这四种,单独记住const修饰成员变量,其他3个可以记住为“const fun(const) const”,一个函数

前、中、后各一个。还有在文中提出的顶层const,它的定义是指针本身的值不能改变,代码上体现为“*”在const的左边;那么当“*”在cosnt的右边时就称为底层const,指针所指的对象不能改变。一个变量可以即为顶层const也可以为底层const。例如:*const* int a。关于const之间的拷贝问题,自己虽然懂,但是没有什么大白话好说,所以暂时就不写了,自己也是死记,才记住的。日后跟理解一点再撸一点感悟。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值