C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++虚表

C++中虚表是什么意思(概念及示例)

作者:江水为竭

虚函数表,以及虚函数指针是实现多态性(Polymorphism)的关键机制,这篇文章主要介绍了C++中虚表是什么意思(概念及示例),需要的朋友可以参考下

虚函数表,以及虚函数指针是实现多态性(Polymorphism)的关键机制。多态性允许我们通过基类的指针或引用来调用派生类的函数

定义

虚函数(Virtual Function)

highlighter- cpp

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

虚函数表(Virtual Function Table)

虚函数指针(Virtual Pointer)

示例

highlighter- cpp

#include <iostream>
using namespace std;
class Base {
public:
    virtual void func1() { cout << "Base::func1" << endl; }
    virtual void func2() { cout << "Base::func2" << endl; }
};
class Derived : public Base {
public:
    void func1() override { cout << "Derived::func1" << endl; }
    // func2() 继承自 Base
};
void printVTable(void* obj) {
    cout << "vptr Address: " << obj << endl;
    void** vTable = *(void***)obj;
    cout << "VTable[0] (func1): " << vTable[0] << endl;
    cout << "VTable[1] (func2): " << vTable[1] << endl;
}
int main() {
    Base* base = new Base();
    Derived* derived = new Derived();
    cout << "Base object:" << endl;
    printVTable(base);
    cout << "\nDerived object:" << endl;
    printVTable(derived);
    delete base;
    delete derived;
    return 0;
}

程序输出如下,可以看到没用重写的func2函数地址是一样的。

highlighter- apache

Base object:
vptr Address: 0x8c1510   
VTable[0] (func1): 0x422270
VTable[1] (func2): 0x4222b0
Derived object:
vptr Address: 0x8c1530   
VTable[0] (func1): 0x422330
VTable[1] (func2): 0x4222b0

如下图所示:

面试题

(来自2024腾讯实习面试)场景题:一个类 A,里面有一个打印 helloworld 的虚函数,然后类 A 会在构造函数里调用这个虚函数,此时有个类 B,继承A,重写了这个 helloworld虚函数,问你在创建类 B 时,会打印 A 里的 helloworld 还是 B 里的。

代码如下:

highlighter- arduino

class A {
public:
    A() {
        print();
    }
    virtual void print() {
        cout << "A print" << endl;
    }
};
class B : public A {
public:
    void print() override {
        cout << "B print" << endl;
    }
};
int main() {
    A* aTemp = new B();
    delete aTemp;
}

解答:基类构造函数执行的时候,派生类的部分尚未初始化,因此调用的虚函数不会下发到派生类中。

最终会打印 A print,而不是类 B 里重写的版本

到此这篇关于C++中虚表是什么的文章就介绍到这了,更多相关C++虚表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文