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


相关推荐
charlie11451419124 分钟前
从 0 开始的机器学习——NumPy 线性代数部分
开发语言·人工智能·学习·线性代数·算法·机器学习·numpy
王老师青少年编程25 分钟前
2025年12月GESP真题及题解(C++七级): 城市规划
c++·gesp·csp·信奥赛·七级·csp-s·提高组
catchadmin1 小时前
Laravel12 + Vue3 的免费可商用商业级管理后台 CatchAdmin V5 正式发布
开发语言·php
袁气满满~_~1 小时前
Python数据分析学习
开发语言·笔记·python·学习
寻星探路2 小时前
【算法专题】滑动窗口:从“无重复字符”到“字母异位词”的深度剖析
java·开发语言·c++·人工智能·python·算法·ai
程序员小白条2 小时前
面试 Java 基础八股文十问十答第八期
java·开发语言·数据库·spring·面试·职场和发展·毕设
Dxy12393102162 小时前
python连接minio报错:‘SSL routines‘, ‘ssl3_get_record‘, ‘wrong version number‘
开发语言·python·ssl
大王小生2 小时前
C# CancellationToken
开发语言·c#·token·cancellation
listhi5202 小时前
基于C#实现屏幕放大镜功能
开发语言·c#
我叫袁小陌2 小时前
C++多线程全面详解
开发语言·c++