从类的内存结构看C++继承

本文通过实例探讨C++中虚函数与虚表的工作原理。解释了虚函数如何实现多态,以及虚表在内存中的构建方式。展示了通过gdb调试获取虚表地址的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本人对C++一直没什么了解,有几次开发用到C++也都没有研究很深,后来跟朋友谈论集成,发现一旦深入内存,类、集成、虚表什么的就变的很美,于是想写下这篇博客记录探究的过程,本文可能有些地方出现错误欢迎大家提出。

一个简单的例子

先看下面这个简单的例子,我们创建一个基类(Base Class),通过简单的继承(Inherit)产生两个派生类(Derived Class),然后通过一个基类的指针去调用这两个派生类,并且调用类中的函数。

class Base {
public:
    int a, b;
    virtual void Show() { cout << "Base class" << endl; }
    void Show2() { cout << "Base class show 2" << endl; }
};

class Derived1: public Base {
public:
    void Show() { cout << "Derived class 1" << endl; }
    void Show2() { cout << "Derived 1 class show 2" << endl; }
};

class Derived2: public Base {
public:
    int c;
    void Show() { cout << "Derived class 2" << endl; }
};

void PrintResult(void)
{
    Base bobj;
    Base *p;
    Derived1 dobj1;
    Derived2 dobj2;

    p = &bobj;
    p->Show();
    p = &dobj1;
    p->Show();
    p = &dobj2;
    p->Show();
}

输出结果如下:

Base class
Base class show 2
Derived class 1
Base class show 2
Derived class 2

基类中定义了虚函数Show(),两个派生类都对重新定义了Show(),虽然是使用基类的指针对类中Show()进行调用,但是,实际执行的是各个类中定义的Show()。但是作为对比,虽然Derived1中对Show2()也进行了定义,但是两次调用所执行的都是Base中定义的Show2()。原因就在于两者性质不同,虚函数的入口是保存在类的虚表中,程序运行的时候才能确定,也就是晚绑定,而Show2(),是直接与类进行绑定的,在程序编译的时候就完成了绑定,也就是早绑定。

本文剩余的部分几乎全部用来讨论虚表的构建和内存结构,来搞清楚继承的时候到底发生了什么。

一个类的虚表

这次换一个稍微复杂一点的:

class Base {
public:
    int i, j;
    virtual void a() { cout << "Base::a" << endl; }
    virtual void b() { cout << "Base::b" << endl; }
    virtual void c() { cout << "Base::c" << endl; }
};

使用gdb进行调试,打印出类所占内存的数据:

(gdb) x /4xg 0x400f70
0x400f70 <_ZTV4Base+16>:    0x0000000000400d24  0x0000000000400d4e
0x400f80 <_ZTV4Base+32>:    0x0000000000400d78  0x6465766972654437

(gdb) x /4xg 0x400f30
0x400f30 <_ZTV7Derived+16>: 0x0000000000400da2  0x0000000000400d4e
0x400f40 <_ZTV7Derived+32>: 0x0000000000400d78  0x0000000000000000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值