C++中的虚函数和虚函数表

简介

C++中的虚函数和虚函数表刚开始学习的时候比较模糊,后来在网上看到了一篇英文的博客,慢慢有了一定的了解和体会,现在做些记录。英文博客地址是 http://www.learncpp.com/cpp-tutorial/125-the-virtual-table/

虚函数表

虚函数表存储的是虚函数的地址,对于每个带有虚函数的类都有一个自己的虚函数表。它们是由编译器在编译时期创建的。并且编译器会为基类加入一个指向虚函数表的指针,这样每次派生类创建自己的对象时,对象都会带有一个指针,该指针指向自己对应类的虚函数表。
下面是一段简单的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Base
{
public:
virtual void function1() {};
virtual void function2() {};
};
class D1: public Base
{
public:
virtual void function1() {};
};
class D2: public Base
{
public:
virtual void function2() {};
};

D1和D2是两个派生类继承自Base,在基类中有两个虚成员函数,而D1和D2分别对function1和function2进行了重写。我们知道在多态中,调用哪个函数取决于指针所指向的对象的类型,那么这个过程是怎么发生的呢?先看看下图中的虚函数表
virtual_table

多态实现

假设我们创建了一个基函数指针

1
2
3
4
5
6
int main()
{
D1 d1;
Base *p = &d1;
p->function1();
}

p是基类指针指向的是对象d1中的基类部分,注意前面说过每个对象都会加上一个虚函数表的指针,而该指针正好是基类部分中的,所以通过指针调用函数function1时,程序会通过p->vptr找到D1的虚函数表,然后查找表中的函数function1,由于function1指针指向D1中的版本,因此就会调用D1中的function1。那么如果我还是想调用Base class中的函数怎么办呢,直接这样写就可以了p->Base::function1()。

声明

若有错误,欢迎讨论。严禁抄袭,仅用于学习。

坚持原创技术分享,您的money将鼓励我继续创作!