• 深入解析C++虚函数表(vtable)和虚指针(vptr)


    2b71dd67fb5b474fadb3f966385938ee.webp

    在C++中,虚函数表(vtable)和虚指针(vptr)是实现多态性的关键机制。

    1. 虚函数表(vtable)和虚指针(vptr)的基本概念

    每个使用虚函数的类都有一个虚函数表(vtable)。vtable是一个包含指向类虚函数的指针的数组。每个对象都有一个虚指针(vptr),指向其类的vtable。当调用对象的虚函数时,实际上是通过vptr和vtable来动态确定要调用哪个函数。

    示例代码:

    1. #include <iostream>
    2. using namespace std;
    3. class Base {
    4. public:
    5.     virtual void show() { cout << "Base class show" << endl; }
    6. };
    7. class Derived : public Base {
    8. public:
    9.     void show() override { cout << "Derived class show" << endl; }
    10. };
    11. int main() {
    12.     Base *bptr;
    13.     Derived d;
    14.     bptr = &d;
    15.     
    16.     // 动态调用正确的函数(Derived::show)
    17.     bptr->show();
    18.     
    19.     return 0;
    20. }

    2. 如何通过虚函数实现多态

    C++中的多态性允许通过基类指针调用派生类的函数。这是通过虚函数(在基类中声明为virtual)和自动维护的vptr和vtable实现的。

    示例代码:

    1. #include 
    2. using namespace std;
    3. class Animal {
    4. public:
    5.     virtual void speak() { cout << "Some animal sound" << endl; }
    6. };
    7. class Dog : public Animal {
    8. public:
    9.     void speak() override { cout << "Woof" << endl; }
    10. };
    11. class Cat : public Animal {
    12. public:
    13.     void speak() override { cout << "Meow" << endl; }
    14. };
    15. void makeAnimalSpeak(Animal* animal) {
    16.     animal->speak();
    17. }
    18. int main() {
    19.     Dog dog;
    20.     Cat cat;
    21.     
    22.     makeAnimalSpeak(&dog);
    23.     makeAnimalSpeak(&cat);
    24.     
    25.     return 0;
    26. }

    3. 虚析构函数

    使用虚析构函数确保当通过基类指针删除派生类对象时,可以正确地调用派生类的析构函数,避免资源泄露。

    示例代码:

    1. #include <iostream>
    2. using namespace std;
    3. class Base {
    4. public:
    5.     virtual ~Base() { cout << "Base destructor" << endl; }
    6. };
    7. class Derived : public Base {
    8. public:
    9.     ~Derived() { cout << "Derived destructor" << endl; }
    10. };
    11. int main() {
    12.     Base *= new Derived();
    13.     delete b; // 正确调用Derived析构函数,然后是Base析构函数
    14.     return 0;
    15. }

    4. 纯虚函数和抽象类

    纯虚函数是一种没有实现的虚函数,其唯一目的是在派生类中进行重写。包含纯虚函数的类称为抽象类,不能实例化。

    示例代码:

    1. #include <iostream>
    2. using namespace std;
    3. class Shape {
    4. public:
    5.     virtual void draw() = 0// 纯虚函数
    6. };
    7. class Circle : public Shape {
    8. public:
    9.     void draw() override { cout << "Drawing Circle" << endl; }
    10. };
    11. int main() {
    12.     // Shape s; // 错误:不能实例化抽象类
    13.     Circle c;
    14.     c.draw(); // 正确:调用Circle::draw
    15.     return 0;
    16. }

    5. 重写 vs 重载虚函数

    虚函数可以在派生类中被重写,这是多态的基础。重写是指派生类提供一个与基类虚函数签名完全相同的函数实现。与之相对的,重载是在同一个类中创建相同名称但参数列表不同的函数。

    示例代码:

    1. #include <iostream>
    2. using namespace std;
    3. class Base {
    4. public:
    5.     virtual void func() { cout << "Base func()" << endl; }
    6.     virtual void func(int x) { cout << "Base func(int)" <<
    7.  endl; }
    8. };
    9. class Derived : public Base {
    10. public:
    11.     void func() override { cout << "Derived func()" << endl; }
    12.     // 注意:这不是重写,因为参数列表不同,这是重载
    13.     void func(int x) override { cout << "Derived func(int)" << endl; }
    14. };
    15. int main() {
    16.     Derived d;
    17.     d.func();       // 调用Derived::func()
    18.     d.func(10);     // 调用Derived::func(int)
    19.     
    20.     return 0;
    21. }

     

  • 相关阅读:
    构建一个商业智能 BI 分析平台,公司CIO应该重点关注什么?
    作业与作业调度--四种调度算法
    transformers架构实现
    任务拆解,悠然自得,自动版本的ChatGPT,AutoGPT自动人工智能AI任务实践(Python3.10)
    pytest-base-url插件之配置可选的项目系统URL
    Linux 的交换空间(swap)是什么?有什么用?
    CSS 文本属性篇
    基于双向长短期记忆 BiLSTM 实现股票单变量时间序列预测(PyTorch版)
    Python 如何实现适配器设计模式?什么是适配器(Adapter)设计模式?
    nodejs+vue教室管理系统的设计与实现-微信小程序-安卓-python-PHP-计算机毕业设计
  • 原文地址:https://blog.csdn.net/karl2000/article/details/136697101