0x02虚函数分析

#include <iostream>
using namespace std;

class Base1 {
public:
    virtual void fun()
    {
        cout << "Base1::fun" << endl;
    }
    virtual void foo()
    {
        cout << "Base1::foo" << endl;
    }
    Base1()
    {
        printf("Base1\n");
    }
    ~Base1()
    {
        printf("~Base1\n");
    }

};

class Base2 {
public:
    virtual void fun()
    {
        cout << "Base2::fun" << endl;
    }
    virtual void foo()
    {
        cout << "Base2::foo" << endl;
    }
    Base2()
    {
        printf("Base2\n");
    }
    ~Base2()
    {
        printf("~Base2\n");
    }
};

class Derive : public Base1, public Base2{
public:
    virtual void fun()
    {
        cout << "Derive::fun" << endl;
    }
    virtual void foo1()
    {
        cout << "Derive::foo1" << endl;
    }
    Derive()
    {
        printf("Derive\n");
    }
    ~Derive()
    {
        printf("~Derive\n");
    }
};


int main()
{

    Derive d;
    Base1 *b1 = &d;
    b1->fun();
    b1->foo();
    Base2 *b2 = &d;
    b2->fun();
    b2->foo();
    return 0;
}

这里写图片描述
根据继承关系的顺序,首先调用了基类Base1的构造函数。在调用另一个基类Base2时, 并不是直接将对象的首地址作为this指针传递,而是向后调整了基类Base1的大小,以调整后的地址值作为this指针,最后再调用基类Base2的构造函数。
由于有了两个基类,因此子类在继承时也将他们的虚表指针一起继承了过来,也就有了两个虚表指针。在多继承中,派生类虚表指针的个数取决于所继承的基类个数。
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述
在转换Base2指针时,je short 001A65E5会调整首地址并跳过第一个基类所占用的空间。
这里写图片描述

这里写图片描述
由于具有多个同级的基类,因此早派生类中产生了多个虚表指针。在对基类进行析构时,需要设置this指针,用于调用基类的析构函数。由于具有多个基类,当在析构的过程中调用各个基类的析构函数时,传递的首地址将有所不同,编译器会根据每个基类在对象中占用的空间位置,对应地传入各个基类部分首地址作为this指针。

总结:

单继承:

  1. 在类对象占用的内存空间中,只保存一份虚表指针。
  2. 由于只有一个虚表指针,对应的也只有一个虚表。
  3. 虚表中各项保存了类中各虚函数的首地址。
  4. 构造时先构造基类,在构造自身,并且只调用一次基类构造函数。
  5. 析构时先析构自身,在析构基类,并且只调用一次基类析构函数。

多重继承类:

  1. 在类对象中所占的内存空间中,根据继承基类的个数保存对应的虚表指针。
  2. 根据所保存的虚表指针的个数,对应产生相应个数的虚表。
  3. 构造时需要调用多个基类构造函数。
  4. 转换基类指针时,需要调转到对应的首地址。
  5. 构造时先构造继承列表中第一个基类,然后依次调用到最后一个继承的基类构造函数
  6. 析构时先析构自身,然后以与构造函数相反的顺序调用所有基类的析构函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值