1.基本概念
C++中的虚函数主要是为了实现多态,就是可以通过父类的指针指向子类的实例并调用子类的成员函数。虚函数有虚函数和纯虚函数,其中纯虚函数是必须在子类中实现的,否则无法实例化该子类。
纯虚函数的格式:
virtual void fun()=0;
虚函数的实现是通过虚函数表(vfptr),每个父类都有一个虚函数表,父类在每个子类的实例中都会自动生成一个虚函数表,可以通过以下方式得到该虚函数表:
typedef void(*fun)(void); Base b; fun pfun = NULL; cout<<"虚函数表地址:"<<(int*)(&b)<<endl; cout<<"第一个虚函数地址:"<<(int*)*(int*)(&b)<<endl; //调用第一个虚函数 pfun=(fun)(*)((int*)*(int*)(&b)); pfun();
虚函数表的结构:
在表中,Base是父类,Derive是子类,当子类中重新实现了父类的虚函数,则相应的虚函数在表中就被覆盖了,而没有重新实现的保留着父类的实现(纯虚函数必须被子类重新实现)
在多重继承中,每个父类都会在子类实例中生成一个虚函数表:
2.实例
#include <iostream> using namespace std; class A{ public: virtual void fun1(){ cout << "Afun1()" << endl; } virtual void fun2(){ cout << "Afun2()" << endl; } virtual void fun3() = 0; void fun4(){ cout << "Afun4()" << endl; } }; class B :public A{ public: virtual void fun1(){ cout << "Bfun1()" << endl; } void fun3(){ cout << "Bfun3()" << endl; } void fun4(){ cout << "Bfun4()" << endl; } }; class C :public A{ public: virtual void fun1(){ cout << "Cfun1()" << endl; } virtual void fun2(){ cout << "Cfun2()" << endl; } void fun3(){ cout << "Cfun3()" << endl; } void fun4(){ cout << "Cfun4()" << endl; } }; typedef void(*fun)(void); //函数指针 int main() { fun pfun = NULL; A *pa; B b; C c; cout << "虚函数表地址:" << (int*)(&b) << endl; cout << "第一个虚函数的地址:" << (int*)*(int*)(&b) << endl; pfun = (fun)*((int*)*(int*)(&b)); pfun();//调用第一个虚函数 pa = &b; pa->fun1(); pa->fun2(); pa->fun3(); pa->fun4(); pa = &c; pa->fun1(); pa->fun2(); pa->fun3(); pa->fun4(); return 0; }
该实例的虚函数表如下: