对象指针
对象作为另外一个类的数据成员
在用堆实例化类时,p指向的是第一个数据成员m_iX
的地址,也可以使用*p
将指针变成对象,来访问相应的数据成员。
来看一个代码例子,这里省略了定义Coordinate类的代码(内有m.iX
和m.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_pCoorA
与m_CoorB
这两个指针
注意,在调用sizeof()
对类时,由于对象成员指针的存在,每个只占四个基本内存单元,会与用栈的方式实例化对象所得到的的结果不同。主要是由于*m_pCoorA
与*m_pCoorB
所指向的内存不是存放在Line
中。
this指针
如果参数和数据成员重名,计算机无法分辨两个而会报错,如下图
this指针就可以解决这种问题
通过this指针为两个同名的函数指向不同的地址,以此来区分同名参数。
这里面就用this ->len
的方式赋值数据成员
复习一下对象结构,实例化多个对象时,它们的数据成员是单独存放的,而成员函数在调用的是同一个。在调用多个对象时函数该如何确定调用哪个数据成员
可以用如下的代码在类中添加this
指针,实际上c++的编译器已经自动添加了this指针,这部分只是用于理解this指针
在调用时如下
在第一行构造函数传入this时指明了this
是arr1
的地址,len
传入10相当于对this
指向的len
赋值10,后面的成语函数同理
在第三行实例化arr2时,this
是arr2
的地址,后面的操作就是对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);
这里不能改变arr1
的len
值
①可以用引用的方法
将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
时,需要在指明返回类型时进行引用或者指针,方可在调用函数操作时对原对象产生影响