在 C++ 中动态联编需要虚函数的支持,这是因为虚函数的工作原理决定的,而正是因为使用了虚函数来实现动态联编,也让动态联编的效率略低于静态联编。通常,编译器处理虚函数的方法是: 给每个对象添加一个隐藏成员,隐藏成员保存了一个指向函数地址数组的指针 ,这个数组就是虚函数表(virtual function table, vtbl)。虚函数表中存储了为类对象进行声明的虚函数的地址,调用虚函数时,程序将查看存储在对象中的 vtbl 地址,然后转向相应的函数地址表,如果使用类声明中定义的第一个虚函数,则程序将使用数组中的第一个函数地址,并执行具有该地址的函数。
虚函数这个概念是 C++ 的精华之一,遇到虚函数时要注意以下几点:
虚析构函数顾名思义就是将析构函数定义为虚函数。如果我们在派生中分配了内存空间,但是基类的析构函数不是虚析构函数,就会发生内存泄漏。看下面的例子:
不加 virtual 的运行结果:
加上 virtual 的运行结果:
在上面程序示加上 virtual 时编译器还是按照 Base 类型调用了析构函数,没有执行 Derived 类的虚析构函数,就造成了内存泄露。修改 Base 类的析构函数为虚析构函数后实现了多态,就可以确保执行正确的析构函数,完成资源的释放。
程序输出: