示例代码
cpp
#include<iostream>
using namespace std;
class A {
public:
int a;
A() {
printf("A:A()的this指针:%p!\n", this);
}
void funcA() {
printf("A:funcA()的this指针:%p!\n", this);
}
};
class B {
public:
int b;
B() {
printf("B:B()的this指针:%p!\n", this);
}
void funcB() {
printf("B:funcB()的this指针:%p!\n", this);
}
};
class C : public A, public B {
public:
int c;
C() {
printf("C:C()的this指针:%p!\n", this);
}
void funcC() {
printf("C:funcC()的this指针:%p!\n", this);
}
};
int main() {
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
cout << sizeof(C) << endl;
C myc;
myc.funcA();
myc.funcB();
myc.funcC();
return 0;
}
输出分析
4
4
12
A:A()的this指针:00000059A22FF968!
B:B()的this指针:00000059A22FF96C!
C:C()的this指针:00000059A22FF968!
A:funcA()的this指针:00000059A22FF968!
B:funcB()的this指针:00000059A22FF96C!
C:funcC()的this指针:00000059A22FF968!
问题 1:A、B、C 三个对象的内存是如何分布的?
在 class C : public A, public B
中,C 同时继承自 A 和 B,A 是第一个基类,B 是第二个基类 。它们在内存中是顺序排列的。

问题 2:如果 C 重载了其父类的方法,传递的 this
是 C 还是父类的?
情况一:没有重载
当 C
没有重写(覆盖)父类的方法时,比如调用 myc.funcB()
:
- 实际调用的是
B::funcB()
。 this
指针会调整为 B 子对象的地址。- 所以
this
!=C
对象起始地址,而是偏移后的地址。
情况二:C 重载了父类的方法
如果你在 C
中重写了 funcB()
:
cpp
void funcB() {
printf("C中重写的funcB()的this指针:%p!\n", this);
}
那么:
myc.funcB()
实际调用的是C::funcB()
。this
是C
对象的起始地址(与A
的起始地址一致)。
总结与补充
内存布局结论
- 在多继承中,派生类对象会顺序排列所有基类子对象的内存布局。
this
指针在非虚继承中只是指向当前类子对象的地址。- 如果基类函数没有被覆盖,调用时
this
指针会偏移到对应子对象。 - 如果被覆盖,则
this
是派生类的完整对象地址。
sizeof
的输出说明
sizeof(A) == 4 // int a
sizeof(B) == 4 // int b
sizeof(C) == 12 // A(4) + B(4) + C::c(4)
补充说明:为什么 A 和 C 的 this 是一样的?
因为 A 是 C 的第一个基类,所以在内存中,A 的子对象从 C 的起始地址开始,C 的 this 指针 == A 的 this 指针。
但是 B 的子对象是紧跟在 A 后面,所有其 this 指针是偏移了一个 int
(4 字节)后的地址。