代码改变世界

白话C++系列(16) -- 常指针和常引用

2016-05-03 22:34  Keiven_LY  阅读(2825)  评论(0编辑  收藏  举报

常指针与常引用

对象的引用和对象的指针

为了说明对象指针与对象引用的相关知识,我们来看一下下面的例子

在这个类中,我们定义了两个数据成员(一个横坐标一个纵坐标),另外,还定义了一个构造函数,还有三个成员函数,其中printInfo()函数是一个常成员函数。那么在实现的时候,也需要在printInfo函数后面加上const关键字来修饰,如下:

下面我们来看看对象的引用和对象的指针如何来定以。

当我们实例化一个对象coor1的时候,我们就可以给这个对象coor1起一个别名叫做coor2(也就是定义一个引用,引用的名字叫做coor2),当从coor2去调用printInfo()的时候,也会打印出coor1的坐标(3, 5)来。同理,当我们去定义一个对象的指针pCoor,如果让它去指向coor1的话,那么使用pCoor去调用printInfo()的时候,也会打印出coor1的坐标(3, 5)。这里需要提醒大家的是,如果我们定义的是对象的引用,我们就可以直接就用那个对象赋值给这个引用;但是当我们定义的是对象指针的时候,我们在给这个指针赋值的时候,一定特别注意给这个对象前面要加上取地址(&)符号,这样才能正确的赋值。说完了对象引用和对象指针后,如果我们在定义的时候,在前面加上const修饰符,这就变成了对象的常引用和常指针了。

对象的常引用和常指针

在这个例子当中,我们定义了一个对象的常引用和对象的常指针,当用coor1去调用printInfo()的时候,肯定不会有问题,会打印出coor1的坐标(3, 5)。关键是当我们用coor2去调用getX()的时候,因为getX这个时候还会传入一个this指针,而这个this指针就是coor2这样的this指针。请注意我们在定义getX和getY的时候,没有在其后面加const,也就是说getX和getY并不是一个常成员函数,这就意味着当用coor2去调用getX()的时候就会出现错误,而出现错误的原因就是因为此时coor2是一个常引用,作为常引用来说,它只有读权限,而getX这里的参数this是一个要求读/写权限的参数,所以其传入的时候就会出现编译错误。所以此时,coor2只能调用其常成员函数。同理使用pCoor来调用getY的时候也是错误的,因为pCoor此时是一个常指针(也只有只读权限)。

下面继续看一个更为复杂的例子。

在这个例子中,实例化了两个坐标对象coor1和coor2,然后又定义了一个对象指针,注意,这里定义的对象指针跟刚刚前面定以的有点不一样。之前const的位置是在Coordinate的前面,现在const放在了*的后面。如果放在*的后面,我们定义的这个pCoor一旦指向了一个对象,那么它就不能再指向另外的对象了。那么我们继续分析下面的三行代码,看看是不是正确。

当pCoor去调用getY,而getY这里要求传入的是可读写权限的对象,而pCoor虽然用const修饰了,但是它的修饰位置是修饰的其本身(意味着这个指针不能指向其他对象),但是这个指针所指向的对象的内容本身是可变的,可见它是一个具有读写权限的指针,只限于它所指向的那个对象可读写,但是它却不能指向其他对象。所以这行代码是正确的。再看下面一行代码,pCoor去指向了coor2,这个就是不允许的(因为pCoor不可以再指向其他对象了),显然这里编译器就会报错。对于第三行代码,pCoor去调用printInfo,显然也是正确的,因为printInfo是一个常成员函数(常成员函数这里传入的this指针要求的是只读权限的),而此时的指针pCoor是具有可读写权限的,所以显然也是正确的。