侧边栏壁纸
博主头像
LittleAO的学习小站 博主等级

在知识的沙漠寻找绿洲

  • 累计撰写 125 篇文章
  • 累计创建 27 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

C++知识点之 虚函数表

LittleAO
2024-08-30 / 0 评论 / 0 点赞 / 9 阅读 / 0 字
温馨提示:
本文最后更新于2024-08-30,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

为了实现多态,我们可以通过基类定义虚函数,派生类重写的方式实现多态。只要一个类声明了虚函数,就会为该类生成一个虚函数表。虚函数表保存了虚函数的地址。当该类实例化了,编译器就会创建这个虚函数表。并为每个对象指向该表。

虚函数表的组成

每个虚函数表包含指向类中所有虚函数的指针。每个虚函数在表中的位置是固定的,与在类中的声明顺序一致。

如果类有虚析构函数,虚函数表中会包含指向该析构函数的指针,确保在通过基类指针删除派生类对象时能正确调用析构函数。

对于包含纯虚函数的类,虚函数表中可能会有指向一个特殊的实现或标记,表示该函数是纯虚的。

基类指针指向派生类

当派生类被构造的时候,就生成了自己的虚函数表和虚指针。即使有一个基类类型的指针指向派生类对象,当调用虚函数时,通过虚指针查找的虚函数表还是派生类的虚函数表,因此执行的还是派生类的函数。

如果没有定义为虚函数,则基类指针运行成员函数一定是基类的成员函数。编译器在编译的时候就已经进行了函数地址的绑定(早绑定),而不是在需要时查询。

编译器处理虚函数表

派生类建立虚函数表三个步骤:

  1. 拷贝基类的虚函数表。多继承则拷贝每一个基类的虚函数表。

  2. 派生类和基类共用一个表,则称该基类为派生类的主基类。

  3. 查看派生类是否重写基类中的虚函数,如果有,就替换表中对应的函数为已经重写的虚函数。派生类是否有自己的虚函数,如果有,则追加自身的虚函数到自身的虚函数表中。

class Base {
public:
    virtual void func1() {
        cout << "Base func1" << endl;
    }
    virtual void func2() {
        cout << "Base func2" << endl;
    }
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void func1() override {
        cout << "Derived func1" << endl;
    }
    virtual void func3() {  // 将 func3 声明为虚函数
        cout << "Derived func3" << endl;
    }
};
类名 虚函数表
Base &Base::func1
&Base::func2
&Base::~Base
---------- -----------------------------------
Derived &Derived::func1 (替换)
&Base::func2
&Base::~Base
&Derived::func3 (追加)

0

评论区