C++核心机制-this 指针传递与内存布局分析

示例代码

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()
  • thisC 对象的起始地址(与 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 字节)后的地址。


相关推荐
2301_79717275几秒前
基于C++的游戏引擎开发
开发语言·c++·算法
比昨天多敲两行1 小时前
C++ 二叉搜索树
开发语言·c++·算法
Season4501 小时前
C++11之正则表达式使用指南--[正则表达式介绍]|[regex的常用函数等介绍]
c++·算法·正则表达式
问好眼2 小时前
《算法竞赛进阶指南》0x04 二分-1.最佳牛围栏
数据结构·c++·算法·二分·信息学奥赛
Birdy_x2 小时前
接口自动化项目实战(1):requests请求封装
开发语言·前端·python
海海不瞌睡(捏捏王子)2 小时前
C++ 知识点概要
开发语言·c++
桌面运维家3 小时前
VLAN配置进阶:抑制广播风暴,提升网络效率
开发语言·网络·php
一轮弯弯的明月3 小时前
Python基础-速通秘籍(下)
开发语言·笔记·python·学习
西西学代码3 小时前
Flutter---回调函数
开发语言·javascript·flutter
大尚来也3 小时前
深入HashMap底层:从JDK1.7到1.8的架构演进与性能突围
开发语言