C++类型转换与this指针调整

在派生类的对象中,基类是作为派生类的子对象存在的,称为基类子对象,当派生类只继承于一个基类时,基类子对象的起始地址是与派生类对象相同的,而当派生类同时继承于多个基类时(多重继承,这里暂不考虑虚拟继承),第一个基类子对象的起始地址是与派生类对象重合的,而后续基类子对象的起始地址与派生类对象依次相差前面的基类子对象的长度,比如,D同时派生于A、B、C,D对象的起始地址是0,那么A子对象的起始地址也是0,B子对象的起始地址是0+sizeof(A),而C子对象的起始地址为0+sizeof(A)+sizeof(B)。在下面的例子中,我们将演示this指针是如何调整的,假设C继承与A、B:

#include <iostream>
#include <stdio.h>
using namespace std;

class A{
public:
	int a;
	A(int i=1) : a(i) {}
	void funA() { printf("A: this = %p\n",this); }
};

class B{
public:
	int b;
	B(int i=2) : b(i) {}
	void funB() { printf("B: this = %p\n",this); }
};

class C : public A, public B {
public:
	int c;
	C(int i = 3) : c(i) {}
	//void funB() {printf("C: this = %p\n",this); }  //#1
};

int main(){

	C cc;
	printf("addr of cc = %p\n",&cc);
	cc.funA();
	cc.funB();
	
	return 0;
}

A、B中各有一个成员变量和成员函数,当C中没有override基类的任何函数时,我们输出了在基类函数中看到的this的值,尽管这些基类函数都是由C对象调用的,输出结果如下:

addr of cc = 0xbfd0a304
A: this = 0xbfd0a304
B: this = 0xbfd0a308

可以看到,C对象的起始地址与A中看到的this是相符的,而与B中看到的相差4,这个4正好是A子对象的大小,所以编译器背后对this的值做了一些调整,如果我们把程序中的#1的注释删掉,也就是在C中override funB(),输出结果就不一样了:

addr of cc = 0xbfbfe824
A: this = 0xbfbfe824
C: this = 0xbfbfe824

可以看到,此时三个值都相同了,因为此时需要将funB()中的this指针指向C对象的起始地址,这样才可以访问C::a。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值