吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1950|回复: 12
收起左侧

[C&C++ 原创] vs2019 下的C++ 多继承对象模型

[复制链接]
loca1h0st 发表于 2025-7-4 22:11
本帖最后由 loca1h0st 于 2025-7-5 01:29 编辑

[C++] 纯文本查看 复制代码
class Base1 {
public:
        virtual void func1() { std::cout << "Base1::func1" << std::endl; }
        virtual void func2() { std::cout << "Base1::func2" << std::endl; }
private:
        int _b1;
};


class Base2 {
public:
        virtual void func1() { std::cout << "Base2::func1" << std::endl; }
        virtual void func2() { std::cout << "Base2::func2" << std::endl; }
private:
        int _b2;
};

class Derive: public Base1, public Base2 {
public:
        virtual void func1() { std::cout << "Derive::func1" << std::endl; }
        virtual void func2() { std::cout << "Derive::func2" << std::endl; }
        virtual void func3() { std::cout << "Derive::func3" << std::endl; }
private:
        int _b1;

};

上面我们定义了两个基类和一个派生类,派生类继承自Base1,Base2 。并在派生类中重写了func1与func2, 这使得在 Derive 对象模型中,func1 和 func2 会分别覆盖掉 Base1 和 Base2 中对应的虚函数表项,即:
  • Base1 的虚表中原本指向 Base1::func1 和 Base1::func2 的函数指针会被替换为 Derive::func1 和 Derive::func2。
  • 同样,Base2 的虚表中原本指向 Base2::func1 和 Base2::func2 的函数指针也会被替换为 Derive::func1 和 Derive::func2。
  • 由于 Derive 还增加了 func3(),因此该函数会被加入到 Derive 中自己的虚函数表(通常在 Base1 的继承路径那边虚表中扩展)。

1

1
下面我们来写段代码来验证一下,到时是不是在Base1的虚表中(vft)
[C++] 纯文本查看 复制代码
typedef void(*VFPTR)();
void printVtable(VFPTR* vTable)
{
    for (int i = 0; vTable[i] != nullptr; i++)
    {
        printf("[%-2d] ==> 0x%p ==> ", i, vTable[i]);
        VFPTR func = vTable[i];
        func();
    }
    cout << endl;
}
int main() 
{
    Derive d;
    cout << sizeof(d) << endl;
    VFPTR* vTable1 = (VFPTR*)(*(int*)&d);
    printVtable(vTable1);

    Base2 b2 = d;
    VFPTR* vtable2 = (VFPTR*)(*(int*)&b2);
    printVtable(vtable2);
    return 0;
}

2

2
我们可以看到在vs2019编译器下,func3 并没有在调试窗口中显示。但是可以通过程序得知,func3 就是保存在Base1的vft中。但是我们仔细观察发现在派生类中重写的func1 在Base1 与 Base2 vft中地址并不一致,这是为什么呢?

3

3


下面通过查看汇编一探究竟

4

4

F11 步进 vs编译器 call 下 一般是jmp指令

5

5
直接跳转到了func1 的地址。那么再来看看ptr2是怎么调用func1的

6

6
连续两次F11 步进

7

7
可以看到ecx - 8。有两个问题ecx 是啥? 为什么减 8 ?
  • ecx  是this 指针
  • 8 是Base1 的大小

8

8

免费评分

参与人数 6吾爱币 +12 热心值 +6 收起 理由
androllen + 1 + 1 谢谢@Thanks!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
156608225 + 2 + 1 鼓励转贴优秀软件安全工具和文档!
Hameel + 1 热心回复!
Bluesky10 + 1 + 1 我很赞同!
DrCatcher + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

情殇丿无痕灬 发表于 2025-7-5 00:42
部分图片一直转圈 我太想进步了
 楼主| loca1h0st 发表于 2025-7-5 01:27
shepherdglen 发表于 2025-7-6 16:16
dongwang_fl 发表于 2025-7-7 22:19
可以学习参考下
yann2009 发表于 2025-7-23 12:27
学习了,从内存层面对多态有了认识
androllen 发表于 2025-7-23 20:04
学习了,感谢大佬分析
iscaswang 发表于 2025-11-12 20:47
技术贴,感谢分享
yuyu2025 发表于 2025-11-13 20:45
我太想进步了
yuyu2025 发表于 2025-11-14 11:31
学习一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-7-15 00:12

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表