c++虚函数解析

来源:互联网 发布:window7下安装ubuntu 编辑:程序博客网 时间:2024/06/08 19:38

1.虚函数的作用---- 当基类指针指向派生类时,使用这个基类指针调用派生类的函数

    多态中派生类和基类之间的特殊关系之一是:基类指针可以在不进行显式类型转换的情况下指向派生类的对象,基类引用可以在不进行显式类型转换的情况下引用派生类对象;

为了区分基类指针调用的函数,是基类的函数,还是派生类的函数,引出了虚函数;

那么,什么是虚函数呢,我们先来看看微软的解释:虚函数是指一个类中你希望重载的成员函数,当你用一个基类指针或引用指向一个继承类对象的时候,你调用一个虚函数,实际调用的是继承类的版本。

这样在使用基类指针指向派生类的对象时,使用基类指针调用相关的函数,就实现对派生类函数的调用;保证调用的相关函数是对象定义时的,相关的类的函数;

2.虚函数调用的实现

  有虚函数的类,一定会有一个虚函数表指针vfptr(virtual table pointer,虚函数表指针), 这个vfptr指针会放在类的起始处,并指向这个类的虚函数表(virutal table); VTABLE是该类的所有对象共有的,在定义该类时被初始化;而VPTR则是每个类对象都有独立一份的,且在该类对象被构造时被初始化。当一个对象调用了虚函数,实际的被调用函数通过下面的步骤确定:找到对象的 vptr 指向的 vtbl,然后在 vtbl 中寻找合适的函数指针。

3.纯虚函数

纯虚函数是在类的声明里声明为 = 0 的函数(具体见下面的示例代码)。纯虚函数有如下特点:

  1. 如果一个类定义了纯虚函数,那么这个类叫虚基类。
  2. 如果一个类定义了纯虚函数,那么将不能在这个类中实现该函数,而只能在继承该类的类中实现。
  3. 如果一个类是虚基类,那么这个类不能实例化对象。
  4. 如果一个类是虚基类,继承它的类并没有实现所有的纯虚函数,那么这个继承它的类也是虚基类。

纯虚函数也能让基类指针所指的子类对象调用到正确的函数。

以下是纯虚函数的例子:

#include <iostream>using namespace std;class A {public:    virtual void foo() = 0; // 声明了一个纯虚函数,A 变成了虚基类,不能实例化对象。};class B : public A {public:    virtual void foo() {        cout << 'B' << endl;    }};int main() {    A *p = new B();    p->foo();    return 0;}

既然说到虚函数和纯虚函数的区别,这里还要说一些虚函数的 FAQ:

  1. 一个类有虚函数,并会让它能实例化一个对象。
  2. 若父类有一个虚函数,子类没有重写父类的这个函数,那么调用的时候,也会调用到父类的这个函数。