一、前言
在C++的学习中我们知道,子类是可以覆盖父类的方法,这里我们探讨一下子类方法调用父类方法时this指针时如何变化的。
二、示例代码
#include "windows.h"
#include "windef.h"
#include <iostream>
#include <tchar.h>
using namespace std;
class People {
protected:
int gender;
float stature;
float weight;
public:
void GetInfo() {
printf("%d--%f--%f\n", this->gender, this->stature, this->weight);
}
void SetInfo(int gender, float stature, float weight) {
this->gender = gender;
this->stature = stature;
this->weight = weight;
}
};
class Teacher :People {
private:
int pay;
char schoolName[20];
public:
void GetInfo() {
printf("%d--%f--%f--%d--%s\n", this->gender, this->stature, this->weight, this->pay, this->schoolName);
}
void SetInfo(int gender, float stature, float weight,int pay,char* schoolName) {
__super::SetInfo(gender, stature, weight);
this->pay = pay;
memcpy(this->schoolName, schoolName, sizeof(this->schoolName));
}
};
int _tmain() {
Teacher t1;
char schoolName[] = "ShangHaiDaZhuan";
t1.SetInfo(1, 120, 180, 102402, schoolName);
t1.GetInfo();
return 0;
}
显然父类的GetInfo被子类覆盖,这里我们将在后面的汇编中简单的查看。注意我们调用子类的SetInfo中调用了父类的SetInfo,我们看看是如何获取People的this指针的
三、详解
首先我们看看栈空间的开辟情况,众所周知,栈是用来保存局部变量的,我们在主函数中创建了俩个局部变量,一个是t1另一个是schoolName[] 我们重点关注t1:
38h-14h=24h=36这满足36=20 * 1 + 4 * 2 + 4 * 2(char
占1字节,int和float占4字节),它开辟了足够的包含父成员变量的空间。
PS:movss在俩个xmm指令寄存器之间或者内存位置和xmm寄存器之间复制标量浮点数
this指针的第一层传递(指向Teacher类的),默认使用ecx进行传递
接下来看看第二层,即SetInfo(子)中是如何传递指向父类的this指针的:
我们发现实际上并没有父类的this指针,其使用的还是Teacher的this指针
父类成员函数是通过子类的this指针偏移寻找到自己所需要的值的如下图: