虚函数,虚表 原理

在 C++ 中,虚函数虚表(VTable)是实现动态多态性的关键机制。通过虚函数,可以在运行时根据实际对象的类型调用相应的函数。

虚表是一个用于存储虚函数指针的表,每个含有虚函数的类都有一个虚表。

虚函数

虚函数是一个在基类中声明的,并且在派生类中可以被重写的函数。关键字 virtual 用于声明虚函数。虚函数允许通过基类指针或引用来调用派生类的函数实现。

#include <iostream>

class Base {
public:
    virtual void show() {
        std::cout << "Base class show function" << std::endl;
    }
};

class Derived : public Base {
public:
    void show() override {
        std::cout << "Derived class show function" << std::endl;
    }
};

int main() {
    Base* b = new Derived();
    b->show();  // 输出: Derived class show function
    delete b;
    return 0;
}

在这个例子中,Base 类中的 show 函数被声明为虚函数,Derived 类重写了该函数。当通过基类指针 b 调用 show 函数时,实际调用的是 Derived 类的 show 函数。

虚表(VTable)

每个含有虚函数的类都有一个虚表(Virtual Table),虚表中存储了指向该类虚函数实现的指针。
对于每个对象,编译器会在对象中添加一个指向虚表的指针,称为虚表指针(VPointer)。通过虚表指针,程序在运行时可以根据对象的实际类型调用相应的虚函数。

虚表的工作原理
类的虚表:编译器为每个含有虚函数的类生成一个虚表。虚表包含该类所有虚函数的指针。
对象的虚表指针:每个对象在其内存布局中包含一个指向其类的虚表的指针。
函数调用:通过基类指针调用虚函数时,程序首先通过对象的虚表指针找到虚表,然后在虚表中找到实际要调用的函数指针,最后调用该函数。

#include <iostream>

class Base {
public:
    virtual void show() {
        std::cout << "Base show()" << std::endl;
    }

    virtual void info() {
        std::cout << "Base info()" << std::endl;
    }
};

class Derived : public Base {
public:
    void show() override {
        std::cout << "Derived show()" << std::endl;
    }

    void info() override {
        std::cout << "Derived info()" << std::endl;
    }
};

int main() {
    Base* b = new Derived();
    b->show();  // 调用 Derived::show()
    b->info();  // 调用 Derived::info()
    delete b;
    return 0;
}

虚表内容
在编译时,编译器会为 Base 和 Derived 类生成如下虚表:

Base 的虚表:

VTable for Base:
[0] Base::show
[1] Base::info

Derived 的虚表:

VTable for Derived:
[0] Derived::show
[1] Derived::info

对象布局
假设 Base 和 Derived 对象在内存中的布局如下:

Base 对象:

[VPTR] -> VTable for Base

Derived 对象:

[VPTR] -> VTable for Derived

调用过程
当通过基类指针 b 调用 show 和 info 函数时,程序执行以下步骤:

1.通过 b 的虚表指针找到 Derived 的虚表。
2.在虚表中找到 show 和 info 函数的指针。
3.调用相应的函数。

总结
虚函数和虚表是 C++ 实现动态多态性的关键机制。虚函数允许在运行时根据对象的实际类型调用相应的函数。虚表是存储虚函数指针的表,每个含有虚函数的类都有一个虚表,每个对象有一个指向虚表的指针。通过虚表,程序在运行时可以高效地实现多态性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值