当前位置: 首页 > news >正文

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

示例代码

#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()

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 字节)后的地址。


相关文章:

  • 读者、写者问题优化
  • 在AMGCL中使用多个GPU和多个计算节点求解大规模稀疏矩阵方程
  • JVM考古现场(十九):量子封神·用鸿蒙编译器重铸天道法则
  • 智能合约安全审计平台——以太坊虚拟机安全沙箱
  • Font Maker的成功之路:产品迭代与创新营销助力增长
  • 国达陶瓷重磅推出陶瓷罗马柱外墙整装尖端新产品“冠岩臻石”
  • Profibus DP主站转modbusTCP网关与dp从站通讯案例
  • 在vue项目中package.json中的scripts 中 dev:“xxx“中的xxx什么概念
  • 爬虫:一文掌握 curl-cffi 的详细使用(支持 TLS/JA3 指纹仿真的 cURL 库)
  • Nacos集群搭建和mysql持久化配置
  • 第三篇:[特殊字符] 深入理解MyBatis[特殊字符] 掌握MyBatis动态SQL——应对复杂查询的有力武器
  • 【vue】轮播图案例
  • 关于python字典的所有操作
  • 性能优化-Spring参数配置、数据库连接参数配置、JVM调优
  • 行锁(Row Locking)和MVCC(多版本并发控制)
  • 空地机器人在复杂动态环境下,如何高效自主导航?
  • ABAP:ME22N控制是否可修改-物料
  • 新晋前端框架技术:小程序容器与SuperApp构建
  • 多模态大语言模型arxiv论文略读(十九)
  • 用 Python 从零构建异步回显服务器
  • 一中国公民在日本滑雪场意外死亡,我领馆发布提醒
  • 医院招聘误发内部信息反获好评,求职者就需要这样的“敞亮”
  • 中央和国家机关工委建立健全整治形式主义为基层减负长效机制
  • 关于沪泰创新合作,泰州市委书记姜冬冬谈到了三个“合”
  • 卡洛·金茨堡:女巫与萨满——我的学术之路
  • 杨小伟被查,国家广播电视总局党组:坚决拥护党中央决定