虚函数调用属于运行时多态,在类的继承关系中,通过父类指针来调用不同子类对象的同名方法,而产生不同的效果。 C++ 中的多态是通过晚绑定(对象构造时)来实现的。 用法 在函数之前声明关键字 virtual 表示这是一个虚函数,在函数后增加一个 = 0 表示这是一个纯虚函数,纯虚函数的类不能创建具体实例。 该示例作后文分析使用,一个包含纯虚函数的父类,一个重写了父类方法的子类,一个无继承的类。 struct Base { Base() : val(7777) {} virtual int fuck(int a) = 0; int val; }; struct Der : public C++中的虚函数是实现运行时多态性的重要机制,它允许通过基类指针或引用调用子类重写的同名方法。这种机制在面向对象编程中非常关键,因为它使得设计更加灵活,允许在不指定具体类型的情况下调用特定的行为。 虚函数的声明是在函数前加上`virtual`关键字。例如,`virtual int fuck(int a)`声明了一个虚函数,该函数接受一个整型参数并返回一个整型值。如果在函数后加上`= 0`,如`virtual int fuck(int a) = 0;`,则该函数成为纯虚函数。纯虚函数的类称为抽象类,不能用于创建实例,但可以作为其他类的基类,这些子类必须实现纯虚函数,否则也将成为抽象类。 在给定的代码示例中,`Base`是一个包含纯虚函数`fuck`的抽象类,`Der`是`Base`的子类,它重写了`fuck`函数。`A`类没有继承关系,也没有虚函数。在`main`函数中,我们创建了一个`Der`对象`der`,然后通过基类指针`pbase`调用`fuck`函数。由于`Base`中的`fuck`是虚函数,所以实际调用的是`Der`类的`fuck`实现,这就是多态性的体现。 虚函数的实现依赖于虚表(Virtual Table,VTBL)。虚表是一个由编译器自动生成的隐含的数据结构,包含了类中虚函数的指针。在类的每个实例中,都有一个指向虚表的指针。当通过基类指针调用虚函数时,实际上是通过这个指针找到虚表,然后根据虚表中的函数指针来调用正确的函数实现。 在反汇编代码中,可以看到`Base`构造函数的部分,它将虚表的地址存储在对象实例的内存中,并且在`Der`的构造函数中,没有额外的操作,因为`Base`的虚函数没有实现,直接调用会导致程序异常。`Der::fuck`函数的实现则是直接访问成员变量`val`并进行计算。 `Der`类重写了`Base`的虚函数`fuck`,在调用`pbase->fuck(sizeof(Der))`时,程序实际执行的是`Der::fuck(int a)`。这是因为编译器在构建对象时,已经为虚函数指针设置了正确的地址,即`Der`类的`fuck`函数地址。这就是C++的晚绑定(Dynamic Binding 或 Late Binding)特性,也称为多态性。 C++的虚函数机制使得我们可以使用基类接口调用子类的方法,从而实现了动态绑定。这种机制在设计模式如工厂模式、策略模式以及各种接口中广泛应用。理解虚函数的工作原理,包括虚表的使用,对于编写高效、灵活的C++代码至关重要。同时,需要注意的是,虚函数会带来一定的性能开销,因为涉及到额外的寻址步骤,所以在不需要多态性的地方应避免使用虚函数。
- 粉丝: 7
- 资源: 930
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助