C++学习笔记-2:const关键字

Posted 汽车人的编程小屋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++学习笔记-2:const关键字相关的知识,希望对你有一定的参考价值。

        对于普通的变量来说,const关键字的作用很简单,就是将其定义为常量


(其值不可更改),套用一张慕课网的截图如下:

图1-const修饰普通整形变量


        在这个例子中,定义了常量x = 3,3这个值就被锁定了,如果后面再赋值x = 4,那么编译时就会报错。这么一看const含义还挺简单的,但是,如果用const修饰指针变量,情况就有些复杂了。




一、const修饰指针和引用


        首先,const的位置不同,其意义也不相同。若const位置在*号之前(const int *p 和 int const *p效果是完全等价的),那么你会发现一个很奇怪的现象,不管是x还是p,其值都没有被锁定,还是可以更改的:

C++学习笔记-2:const关键字

图2-const修饰指针(形式1:const在*之前)


        此时可以用x = 4更改x的值,也可以重新定义一个整型int y = 5;然后通过p = &y使指针p指向y。调取(*p),也会是更改后的值。唯独不同的是,(*p)的值不允许被更改了。你可以更改原变量x使(*p)改变,也可以改指针指向从而使(*p)改变,但是直接更改(*p)不行!




C++学习笔记-2:const关键字

图3-const修饰指针(形式2:const*之后


        如果先用const修饰了x,那么x的值也被锁定了,此时x和(*p)的值都修改不了了。




        更特别地,可以在*号前后各加一个const关键字(同样, 前一个const在int前还是后都无所谓)。这样,不管是p的指向还是(*p)的值,都不可更改了。

        然而你const修饰p跟我x有什么关系?x的值仍是可以更改的。只有定义x的时候也用const修饰,才是全方位锁死,真正地变成一个常量了。

C++学习笔记-2:const关键字

图4-const修饰指针(形式3:双重锁定




        既然关键字const可以修饰指针,那它可以修饰引用吗?当然可以!不过通过下图可以看出,const修饰引用时只限制了别名y,也没有影响到原本的变量x。

C++学习笔记-2:const关键字

图5-const修饰引用


        所以,与其说const关键字定义了常量,不如说const关键字更改了程序访问变量的权限:由原来的可读可写,变为了只读权限。const的位置不同,决定了被赋予只读权限的变量范围不同。




二、const修饰数据成员、对象成员与成员函数


        在C++中定义类的时候,const不仅可以修饰简单的数据成员(基本数据类型),还可以修饰对象成员(类的实例化对象,引用数据类型)和成员函数(类的方法)。下面我以几个简单的类为例说明:


C++学习笔记-2:const关键字

图6-const修饰数据成员


        如图6,建立一个Coordinate(坐标)类,定义两个私有数据成员(坐标x和y)。因为希望实例化Coordinate对象时,x和y坐标值就不要再变动了,所以用const修饰。

        但这就带来一个问题,用const修饰后,即使是构造函数,也无法对x和y进行赋值。这就需要用到初始化列表:

C++学习笔记-2:const关键字

图7-使用初始化列表设置x和y的值


        接着,再定义一个Line(线段)类,以两个Coordinate对象(线段的两个端点)作为其私有对象成员。因为希望线段创建后端点也不要移动,所以可以用const修饰之:

C++学习笔记-2:const关键字

图8-const修饰对象成员


        同样地,端点的坐标需要通过初始化列表来设置。


C++学习笔记-2:const关键字

图9-使用初始化列表设置端点坐标

        可以看出const修饰数据成员和对象成员的用法区别不大。


        现在,我取消const对x和y坐标的修饰,写两个changeX(改变x坐标的值)的函数,在其中一个末尾加上const。加上const的这个成员函数就被称为常成员函数。

C++学习笔记-2:const关键字

图10-声明常成员函数


        这两个同名为ChangeX的函数,是有互为重载的关系的,都需要写代码实现。但是,在常成员函数的实现中,不能修改数据成员的值。

C++学习笔记-2:const关键字

图11-常成员函数不能更改数据成员的值


        在函数的调用上也有所区别,如果实例化了一个不用const修饰的coordinate对象,那么它调用changeX函数时优先调用的是不用const修饰的普通成员函数。如果用const修饰为常对象,那么调用时只会调用常成员函数。

C++学习笔记-2:const关键字

图12-常对象只能调用常函数,非常对象优先调用非常函数




三、常对象指针和常对象引用


        现在,我们了解到了const修饰整形变量、指针变量、引用、以及对象实例时的效果。但对象也可以定义指针来指向,或者定义别名,称为对象指针和对象引用。它们用const修饰时会产生什么效果呢?

C++学习笔记-2:const关键字

        通过类比法我们可以推测一个大致的结论,下面我们继续以例子来说明:

        同样是Coordinate类,定义获取坐标值x和y的函数以及一个展示坐标的常对象函数printInfo

C++学习笔记-2:const关键字

图13-声明展示坐标的函数


C++学习笔记-2:const关键字

图14-实现展示坐标的函数


        然后,实例化一个坐标coor1,并分别定义指针pCoor指向coor1,以及其别名coor2。

        对于coor1对象来说,它未被const修饰,getX、getY和printInfo都能调用。

        对于pCoor来说,const位置在*号之前,所以它可以改变指向,但是不能调用非常成员函数,只能调用printInfo。

        而coor2是一个常对象别名,权限受限,只能调用printInfo。

C++学习笔记-2:const关键字

图15-常对象指针和常对象引用权限受限制


图16-不可更改指向但可以调用非常对象函数


        因此,我们可以将const修饰数据和对象(and 指针和引用)的效果总结为:




有什么看法或建议欢迎写在留言区:

以上是关于C++学习笔记-2:const关键字的主要内容,如果未能解决你的问题,请参考以下文章

C++学习笔记关于const int* int const * int* const

c++学习笔记2--constexpr,类型别名,auto

C++学习笔记1:类的使用

c++学习笔记--复合类型,const。

effective c++学习笔记

《Effective C++》学习笔记