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


相关推荐
JAVA学习通27 分钟前
北京明光云振铎数据科技Java面经
java·开发语言·科技
jerryinwuhan7 小时前
基于各城市站点流量的复合功能比较
开发语言·php
迈巴赫车主7 小时前
Java基础:list、set、map一遍过
java·开发语言
智者知已应修善业7 小时前
【51单片机89C51及74LS273、74LS244组成】2022-5-28
c++·经验分享·笔记·算法·51单片机
南 阳9 小时前
Python从入门到精通day66
开发语言·python
十八旬10 小时前
快速安装ClaudeCode完整指南
开发语言·windows·python·claude
前进的李工10 小时前
EXPLAIN输出格式全解析:JSON、TREE与可视化
开发语言·数据库·mysql·性能优化·explain
Byron Loong10 小时前
【c++】为什么有了dll和.h,还需要包含lib
java·开发语言·c++
独隅11 小时前
CodeX + Visual Studio Code 联动的全面指南
开发语言·php
坚果派·白晓明11 小时前
【鸿蒙PC三方库移植适配框架解读系列】第一篇:Lycium C/C++ 三方库适配 — 概述与环境配置
c语言·开发语言·c++·harmonyos·开源鸿蒙·三方库·c/c++三方库