我们知道C++是一门面向对象的语言,它有三大特性:封装、继承、多态。其中多态是最具有面向对象程序设计的特性。
多态分静态多态和动态多态。静态多态也称编译时多态,指通过函数重载、运算符重载等,根据参数列表在编译时刻确定调用函数。动态多态也叫运行时多态,是在运行时刻才确定调用的函数,运行时多态是通过类中的虚函数实现的。
在类的函数声明前加上关键字virtual,该函数就是一个虚函数了。编译器会给有虚函数的类在全局数据区里分配一块虚函数表(Virtual Table),虚函数表的每一项对应该类的虚函数地址。隐式的编译器还在类中插入第一个成员——类的虚函数表指针。此后,当调用该类的虚函数时,编译器不是硬编码函数地址,而是间接调用虚函数表对应项的函数地址。另外编译器会在每个构造函数代码前生成初始化虚函数表指针的代码(指向本类的虚函数表)。
当派生类继承带有虚函数的基类时,理所当然的也将继承其虚函数表,派生类虚函数表的开头部分顺序拷贝自基类,之后才是派生类自己的虚函数表项。当然派生类也可以覆盖掉基类的虚函数(改写虚函数表项内容),只要在派生类中重新定义基类的虚函数(可以不加virtual关键字,不加的话影响可读性),覆盖函数的名字、参数列表、返回值、调用约定必须与被覆盖函数相同。虚函数通过间接调用的方式,实现了继承自同一个基类的不同派生类,调用同一个基类虚函数,却实现不同的功能,这样就形成了类的多态。
最后VC6对虚函数调用作了一点优化,只有当对象指针或引用方式调用虚函数时,才会通过虚函数表间接调用,如果是使用对象直接(成员访问运算符)调用,编译器在编译时会生成虚函数地址的硬编码,而非间接调用。
科锐课堂笔记:2017/4/19 虚函数
最新推荐文章于 2019-01-17 21:00:06 发布