C++自学笔记(12)之对象指针

对象指针

对象作为另外一个类的数据成员

在这里插入图片描述
在用堆实例化类时,p指向的是第一个数据成员m_iX的地址,也可以使用*p将指针变成对象,来访问相应的数据成员。
来看一个代码例子,这里省略了定义Coordinate类的代码(内有m.iXm.iY两个数据成员),只写main函数里面实例化对象部分

Coordinate p1;
Coordinate *p2=&p1;   //声明对象指针

p2->m.iX=10;   //通过对象之这对p1的数据成员进行赋值
p2->m.iY=20;   //也可以用       (*p2).m_iY=20;     

cout<<p1.m_iX<<endl;
cout<<p1.m_iY<<endl;

打印出来的p1的两个成员数据与p2指定的值相同。

对象成员指针

对象的指针作为另外一个类的数据成员
如下图,定义两个类。其中Line的数据成员通过指针用堆的方式调用Coordinate
在这里插入图片描述
在对Line初始化时,可以用初始化列表的方式,也可以用普通析构函数的方式(而用栈实例化时其他类时只能用初始化列表)
在这里插入图片描述
在需要析构函数设定默认值时可以写成如下形式,最后要在析构函数中销毁m_pCoorAm_CoorB这两个指针
在这里插入图片描述
注意,在调用sizeof()对类时,由于对象成员指针的存在,每个只占四个基本内存单元,会与用栈的方式实例化对象所得到的的结果不同。主要是由于*m_pCoorA*m_pCoorB所指向的内存不是存放在Line中。
在这里插入图片描述

this指针

如果参数和数据成员重名,计算机无法分辨两个而会报错,如下图
在这里插入图片描述
this指针就可以解决这种问题
在这里插入图片描述
通过this指针为两个同名的函数指向不同的地址,以此来区分同名参数。
在这里插入图片描述
这里面就用this ->len的方式赋值数据成员

复习一下对象结构,实例化多个对象时,它们的数据成员是单独存放的,而成员函数在调用的是同一个。在调用多个对象时函数该如何确定调用哪个数据成员
在这里插入图片描述

可以用如下的代码在类中添加this指针,实际上c++的编译器已经自动添加了this指针,这部分只是用于理解this指针
在这里插入图片描述
在调用时如下
在这里插入图片描述
在第一行构造函数传入this时指明了thisarr1的地址,len传入10相当于对this指向的len赋值10,后面的成语函数同理
在第三行实例化arr2时,thisarr2的地址,后面的操作就是对this指向的arr2操作
ps:由于前面说到的编译器已经自动添加了this,在对数据成语对象赋值时写成如下形式即可,使用时不用考虑this指针。
在这里插入图片描述

下面来看一段代码例子,看看this指针在实战中的作用
创建一个类Array,在array.h代码如下

#include <iostream>
#pragma once
using namespace std;
class Array
{
public:
	Array();
	//~Array();
	void setLen(int len);
	int getLen();
	Array printInfo();
private:
	int len;
};

array.cpp代码如下

#include <iostream>
#include "Array.h"
using namespace std;

Array::Array()
{
	cout << "Array" << endl;
}

void Array::setLen(int len)
{
	this->len =len;   //这里用this指针指向类的地址,用以区分参数及数据成员
}
int Array::getLen()
{
	return len;       //无参数,调用的一定是成员对象
}
Array Array::printInfo()    //这里Array是返回对象
{
	cout << "len=" << len << endl;
	return *this;         //返回的是this指针指向的对象
}

主函数中代码如下

#include <iostream>
#include<stdlib.h>
#include <string.h>
#include "Array.h"

using namespace std;

int main(void)
{
	Array arr1;    //实例化为对象arr1
	arr1.setLen(10);
	arr1.printInfo().setLen(5);   //对printInfo返回的对象设置setLen
	cout << "len=" << arr1.getLen() << endl;
	
	system("pause");
	return 0;
}

结果如下
在这里插入图片描述
前后的len都为10是因为在printInfo函数定义的返回值类型Array与arr1实例化的对象不是同一个,故arr1.printInfo().setLen(5);这里不能改变arr1len

①可以用引用的方法
printInfo函数改为如下

Array& Array::printInfo()    //这里Array&是返回后面arr1的引用
{
	cout << "len=" << len << endl;
	return *this;         //返回的是this指针指向的对象
}

同时注意将h文件的声明Array printInfo();改为Array& printInfo();
输出结果如下
在这里插入图片描述

②可以用指针的方法
printInfo函数改为如下

Array* Array::printInfo()    //这里Array&是返回后面arr1的指针
{
	cout << "len=" << len << endl;
	return this;         // 由于返回值已经是指针,this本身就是指针,不需要加*
}

同时注意将h文件的声明Array printInfo();改为Array* printInfo();
主函数的arr1.printInfo().setLen(5);改为arr1.printInfo()->setLen(5); //因为printInfo返回值是指针,故用->形式
输出结果同①

总结一下,在这个例子中this指针的地址和arr1的地址(即&arr1)是一样的, 返回类型为类本身,返回值为this时,需要在指明返回类型时进行引用或者指针,方可在调用函数操作时对原对象产生影响

猜你喜欢

转载自blog.csdn.net/qq_39672732/article/details/88907053