65 C++对象模型探索。this指针, this 指针在多继承的时候有可能发生调整

本文详细解释了C++中this指针的作用,如何在成员函数中确定调用对象,以及在子类继承和多重继承情况下的this指针行为。重点介绍了this指针的位置、静态成员函数与this的关系,以及派生类中this指针的调整机制。
摘要由CSDN通过智能技术生成

这一节我们研究的是 this指针

那么C++中类成员函数是如何知道哪个对象调用了它?并正确显示调用它的对象的数据呢?

Teacher tea;

Teacher tea2;

tea.func();

tea2.func();

当x.func()时候,func函数怎么知道是tea调用的?还是tea2调用的?换句话说:怎么知道x的地址是tea还是tea2?

实际上当一个对象x调用func的时候,会隐式的将自己的地址传进去,这个隐式的参数就是this指针,this指针中存放的就是这个对象的首地址。


当一个对象调用某成员函数时会隐式传入一个参数, 这个参数就是this指针。this指针中存放的就是这个对象的首地址。


这和C中通过向函数传递结构体变量的地址是不是很像?只是传参形式不一样罢了! 在C中我们是手工把结构体变量和函数关联起来的,而C++则是编译器帮我们把类数据和成员函数关联起来的并通过名称粉碎和编译时检查等形式防止外部的任意访问。
 

那么这个this指针存放在哪里呢?


其实编译器在生成程序时加入了获取对象首地址的相关代码。并把获取的首地址存放在了寄存器ECX中(VC++编译器是放在ECX中,其它编译器有可能不同)。也就是成员函数的其它参数正常都是存放在栈中。而this指针参数则是存放在寄存器中。
类的静态成员函数因为没有this指针这个参数,所以类的静态成员函数也就无法调用类的非静态成员变量。
 

当一个子类继承一个父类。子类对象的this指针和父类对象的this指针对比。

class Teacher4 {
public:
	Teacher4() {
		cout << "Teacher4::Teacher()的this 指针是 " << this << endl;
	}
	void func4() {
		cout << "Teacher4::func4()的this 指针是 " << this << endl;
	}
	int mage4;
};

class Teacher6 :public Teacher4 {
public:
	Teacher6() {
		cout << "Teacher6::Teacher()的this 指针是 " << this << endl;
	}
	void func6() {
		cout << "Teacher6::func6()的this 指针是 " << this << endl;
	}
	int mage6;
};

void main() {
	cout << sizeof(Teacher4) << endl; //4
	cout << sizeof(Teacher6) << endl; //8
	Teacher4 tea4;//Teacher4::Teacher()的this 指针是 00000019BCCFF7E4
	Teacher6 tea6;//Teacher4::Teacher()的this 指针是 00000019BCCFF808  Teacher6::Teacher()的this 指针是 00000019BCCFF808
	cout << sizeof(tea4) << endl; //4
	cout << sizeof(tea6) << endl; //8

	cout << " &tea4 = " << &tea4 << endl;//&tea4 = 00000019BCCFF7E4
	cout << " &tea6 = " << &tea6 << endl; //&tea6 = 00000019BCCFF808

	tea4.func4(); //Teacher4::func4()的this 指针是 00000019BCCFF7E4
	tea6.func4(); //Teacher4::func4()的this 指针是 00000019BCCFF808
	tea6.func6(); //Teacher6::func6()的this 指针是 00000019BCCFF808

	//从上面看到,&tea4 和 &tea6 中 this 指针是同一个。


}

从结果上看:子类用的this指针,实际上是父类的this指针

当子类继承了多个父类,那么子类对象中的this指针是那个父类的呢?

this指针调整:多存在于多重继承的情况下。

class Teacher7 {
public:
	Teacher7() {
		cout << "Teacher7::Teacher()的this 指针是 " << this << endl;
	}
	void func7() {
		cout << "Teacher7::func7()的this 指针是 " << this << endl;
	}
	int mage7;
};

class Teacher8 {
public:
	Teacher8() {
		cout << "Teacher8::Teacher()的this 指针是 " << this << endl;
	}
	void func8() {
		cout << "Teacher8::func8()的this 指针是 " << this << endl;
	}
	int mage8;
};
class Teacher9 :public Teacher7, public Teacher8{
public:
	Teacher9() {
		cout << "Teacher9::Teacher()的this 指针是 " << this << endl;
	}
	void func9() {
		cout << "Teacher9::func9()的this 指针是 " << this << endl;
	}
	int mage9;
};
//多继承时用的是那个this指针
void main() {
	Teacher7 tea7;//Teacher7::Teacher()的this 指针是 000000C93E54FCB4
	cout << "&tea7 = " << &tea7 << endl;//&tea7 = 000000C93E54FCB4
	Teacher8 tea8;//Teacher8::Teacher()的this 指针是 000000C93E54FCD4
	cout << "&tea8 = " << &tea8 << endl; //&tea8 = 000000C93E54FCD4
	Teacher9 tea9;
	//	Teacher7::Teacher()的this 指针是 000000C93E54FCF8
	//  Teacher8::Teacher()的this 指针是 000000C93E54FCFC
	//  Teacher9::Teacher()的this 指针是 000000C93E54FCF8,说明子类中的this 用的是 第一个继承的父类

	cout << "&tea9 = " << &tea9 << endl;//&tea9 = 000000C93E54FCF8

	tea7.func7(); //Teacher7::func7()的this 指针是 000000C93E54FCB4
	tea8.func8();// Teacher8::func8()的this 指针是 000000C93E54FCD4
	tea9.func7();//Teacher7::func7()的this 指针是 000000C93E54FCF8
	tea9.func8();//Teacher8::func8()的this 指针是 000000C93E54FCFC
	tea9.func9();//Teacher9::func9()的this 指针是 000000C93E54FCF8
		
	//如果换成class Teacher9 :public Teacher8, public Teacher7 那么tea9的this对象就是父类的tea8的

}

结论:

A,如果派生类只从一个基类继承,那么派生类对象的起始地址和基类对象的起始地址是一样的。

B ,如果派生类从多个基类继承,那么派生类对象的起始地址 和 继承的第一个 基类对象的地址相同,后面这些基类对象的开始地址和派生类对象的开始地址相差多少呢?那就要把前面的基类对象锁占用的空间内存减掉。

C ,this就是对象的起始地址,假设 TeacherC,继承了TeacherA,继承了TeacherB,那么teac.func();this指针是和teaa的this指针是同一个。当调用teac.funb()的时候,this指针就会发生变化,这时候this指针和teab的this指针是同一个。这就叫做 this指针调整

D,this就是对象的起始地址,假设 TeacherC,继承了TeacherB,继承了TeacherA,那么teac.func();this指针是和teab的this指针是同一个。当调用teac.funa()的时候,this指针就会发生变化,这时候this指针和teaa的this指针是同一个。这就叫做 this指针调整

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值