大家好
欢迎回来继续学习
C++语言程序设计
这一节呢
我们来学习对象指针
对象指针呢
也就是用来容纳
一个对象地址的指针
它指向的是对象
接下来我们就来看
对象指针的定义和使用
我们来看定义一个对象指针呢
实际上跟定义其他类型的指针
是一样的
都是指针名
前面有个*
再往前呢是类型名
那么类名也就是个类型名
对吧
所以我们看这段程序代码的例子
比如说我们定义一个
point类型的指针 ptr
也就是说
这个指针是准备着用来存放
point对象地址的
那么在此之前呢
我们已经定义
已经构造了一个point对象a
所以我们就可以将a的地址
赋给这个指针
所以这跟一般的
指向数据变量的指针是一样的
但是呢
我们用指针去访问
所指向的对象的时候
怎么访问呢
我们去访问对象
一般都是要通过对象
去访问对象的成员
公有的接口 对吧
所以我们怎么样通过对象指针
去访问对象成员呢
那么这里给出的呢
是一个非常简洁的形式
就是对象指针名
好象然后是一个箭头
后面是成员名
其实那不是一个箭头
是一个减号后接一个大于号
都是西文符号
但是它的样子就像箭头
它的含义也是一个指向的含义
那么它实际上
语法上等同于什么呢
比如说ptr箭头getx
那就等同于
我用ptr这个指针进行指针运算
那么就找到了它指向的对象
就是对象a
那么通过a去访问
通过对象去访问
它的公有成员函数的时候
我们当然是通过
对象名.成员名的方式访问了
所以呢
实际上就是*ptr（）.getx
这是我们原本的通过指针
访问对象的公有成员的方式
但是这种写法呢
毕竟过于繁琐
所以在C++中呢
一般推荐另外一种写法
就是用一个
像箭头一样的东西指过去
ptr减号大于号
合起来算个箭头吧
然后getx 这样来访问
接下来在下面这个例题中呢
我们就要用指向对象的指针
来访问point类的对象
在这个程序中呢
我们在主函数中
定义了点类的对象a
然后又定义了
指向点类对象的指针p1
用已经定义好的对象a的地址
去初始化p1
这样的话
p1是指向对象a了
那么用p1去访问对象a
怎么访问呢
我们知道
实际上我们可以用*p1
指针运算符去访问
但是访问到对象a以后
我们还要再去找
它的函数
那么还要点 函数
*().点合起来
可以转化成另外一种形式来写
就是箭头是一个减号大于号
用p1去访问了对象a的getx函数
那再看看接下来用a
去访问getx函数
如果我们自己去运行一下
看一下输出结果
你会发现它的效果是一样的
大家可以课后
自己去运行一下这个程序
接下来
我们要学习一个很好玩的指针
this指针
它是什么呢
是指向当前对象自己的指针
为什么有的指针
还要指向当前对象自己
这个当前对象说的是什么
是谁
我们想想
当我们用对象名.函数名的方式
去调用对象的接口函数的时候
公有函数的时候
比如说
我们用对象名.getx
这个getx函数
就会把这个对象的x数据成员值
返回回来
其实大家有没有想过
这样一个问题
当你在调用getx这个函数的时候
其实可能
不止一个对象被构造过
在当前系统中
存在着好几个对象了
这个getx怎么就能知道
去把谁的x坐标反馈回来呢
那么知道了this指针是怎么回事
这个问也就解决了
实际上呢
这个this指针
它是隐含于类的每一个
非静态的成员函数中的
也就是
属于对象的成员函数
像比如point类的getx函数
gety函数
它肯定是属于对象的
必须通过
对象名.函数名的方式访问
它会准确地把这个对象的x坐标
y坐标反馈回来
那原因就是
在这样的非静态成员函数
都隐含着有一个this指针
那么比如说
我们调用一个getx函数的时候
貌似这个getx函数
它没有参数
参数表是空的
貌似我们的调用
没有给它传任何参数进去
但是实际上
暗地里传给它了一个东西
是什么
是当前这个对象的地址
你总要通过对象名.getx调用吧
这个对象的地址
就被传给getx函数了
那么这个getx函数内部呢
隐含的有一个指针
指针变量名叫做this
那么当前对象的地址
就传到this里面去了
所以在getx函数中
我们有return x这样一条语句
它就实际上相当于
return这个this
指针所指向对象的x
所以现在大家明白了吧
在此之前有的同学
已经有这样的疑问了
说为什么我进到getx函数里面
去以后
这个函数知道它从哪儿来的呢
知道是谁调用的它呢
按说进到函数体里头以后
这个函数是不知道
它的执行流程从哪儿进来的
不知道谁调用了它的
怎么它就那么巧
能把当前对象的这个x值
给返回呢
现在这个疑问解决了吧
大家还记得
在前面我们讲
前向引用声明的时候
给大家演示的那个错误的例子吧
好 现在呢
就给出正确的解决方案
这是我们在前面
讲前向引用声明的时候
出现过的例子
这个Barney类里面呢
有一个对象成员是Fred类对象
Fred类呢有个对象成员
是Barney类对象
结果把它们两个谁写前头
都不合适
用了前向引用声明
还是不解决问题
为什么呢
当你没有见到一个类的
完整定义的时候
是不能使用它的细节的
也就是说
不能去定义Fred类对象
编译器无法处理
不知道要给它多少字节的空间
至少这个细节信息是必须的
那这个没有
怎么办呢
现在我们可以变通一种做法
这个就是一个正确的解决方案
我们可以在Barney类里面
定义一个指向Fred对象的指针
那么只有一个指针
并没有Fred对象啊
没关系
你可以在构造函数中
在构造这个对象的时候
去用new运算做动态内存分配
分配一个Barney类的对象
将它的首地址赋给x这个指针
效果就达到了
就可以完成在Barney类里面
有Fred对象
在Fred类里面有Barney
对象的这样一个效果了
但是同学们肯定会觉得
我什么时候会需要这个效果呀
两个类对象
互相包含对方的子对象
其实有这样需求的时候其实很少
这个纯粹为了说明语法现象
这是一个验证性的例子