C++ 虚函数和动态多态性
在基类的声明中使用关键字virtual并在派生类中重新定义(覆盖)的成员函数被称为虚函数。后期绑定指令指示编译器通过将对象与相应的被调用函数相匹配来在运行时执行调用的函数。运行时多态性就是指这种方法。
- 无论使用什么类型的引用(或指针)来调用函数,虚函数都确保为对象调用正确的函数。
- 它们的主要目的是实现运行时多态性。
- 在基类中,函数使用关键字virtual进行声明。
- 执行函数调用的运行时解析会被执行。
多态性是用来描述能够呈现多种形态的能力的术语。当存在一个通过继承相互连接的类层次结构时,就会发生多态性。多态性被定义为“在不同的上下文中展示不同的特征”,可以归纳为“在各种情况下展示不同的特征”和“多态性”。
虚函数的用途是什么
为了实现运行时多态性,主要使用虚函数。只有基类类型的指针(或引用)可以实现运行时多态性。基类指针还可以指向来自基类和派生类的对象。
此外,即使不知道派生类对象的类型,我们也可以使用虚函数编译一个基类指针列表并调用任何派生类的方法。
示例
#include
using namespace std;
class B {
public:
virtual void s() {
cout<<" In Base \n";
}
};
class D: public B {
public:
void s() {
cout<<"In Derived \n";
}
};
int main(void) {
D d; // An object of class D
B *b= &d // A pointer of type B* pointing to d
b->s(); // prints "D::s() called"
return 0;
}
输出:
虚函数有哪些规则
- 虚函数不能是静态的,也不能对其他类友好。
- 必须使用基类类型的指针或引用来访问虚函数。
- 基类和派生类都应该使用相同的函数声明。
- 类中不能有虚构造函数,但可以有虚析构函数。
- 基类总是定义它们,派生类重新定义它们。
什么是运行时多态性
运行时多态性是将对象在运行时与其能力绑定的过程。重写方法是实现运行时多态性的一种方式。在运行时,而不是在编译时,Java虚拟机决定调用哪个方法。也称为动态绑定或晚期绑定。根据这个概念,在子类中重写了父类的方法。术语“方法重写”是指子类实现了由其父类之一提供的特定方法。你可以在下面的示例中看到运行时多态性的示例。
示例
class Test {
public void method()
{
System.out.println("Method 1");
}
}
public class DEMO extends Test {
public void method()
{
System.out.println("Method 2");
}
public static void main(String args[])
{
Test test = new DEMO();
test.method();
}
}
输出:
虚函数是如何工作的
如下所述,如果一个类有虚函数,编译器会执行两个任务。
- 如果创建了该类的对象,编译器会在该类中添加一个指向类的虚函数表(VTABLE)的虚指针(VPTR)作为数据成员。每创建一个新对象,就会为该类添加一个新的虚指针作为数据成员。
- 无论是否生成对象,虚函数表(VTABLE)都是该类的一个静态函数指针数组的成员。该表的每个单元格都包含了该类中的虚函数的地址。
虚函数有哪些限制
- 速度较慢:虚函数机制导致函数调用需要更长的时间,使得编译器在优化时更难确定编译时将调用哪个函数。
- 在复杂系统中,虚函数可能使得确定函数的调用源变得更加困难,这使得调试更具挑战性。