在MFC编程中遇到了两种虚函数的特性,看如下代码,B继承于A,C继承于B,D继承于C,E继承于D,F继承于E。
第一种特性:
#include <iostream> using namespace std; class A { public: virtual void vFunc(); }; class B:public A { public: virtual void vFunc(); }; class C: public B { public: virtual void vFunc(); }; class D: public C { public: //virtual void vFunc(); }; class E: public D { public: //virtual void vFunc(); }; class F: public E { public: virtual void vFunc(); }; void A::vFunc() { cout << "vFuncA "; } void B::vFunc() { cout << "vFuncB "; } void C::vFunc() { cout << "vFuncC "; } //void D::vFunc() //{ // cout << "vFuncD "; //} //void E::vFunc() //{ // cout << "vFuncE "; //} // void F::vFunc() { cout << "vFuncF "; } void F::show() { D::vFunc(); } void main(void) { C cc;
C *ptr1 = &cc; //用派生类类型指针指向派生类对象地址,没有类型转换 cc.vFunc(); //用对象调用
ptr1->vFunc();//用指针调用
//----------------------------------------------------特性一;
A *ptr2 = &cc; //用基类指针指向派生类对象地址,有类型转换
ptr2->vFunc();//用指针调用
//----------------------------------------------------特性二; getchar(); }
主函数中创建类C的对象,用ptr指针来指向这个对象,1:然后调用虚函数vFunc(), 运行结果为vFuncC,分析原因:即使D、E、F类都继承了C类且互相继承,但是调用虚函数vFunc还是没有显示他们当中的一个,因为我们只是创建了C这个对象,它只会创建它的父类B、C部分,而不会创建D、E、F部分,因此只会得到vFuncC。
2、如果我们把类C的虚函数vFunc注释掉,运行结果就是vFuncB,因为根本原因是虚函数表的覆盖问题,没注释之前,由于类C的虚函数表中的vFunc覆盖了类B的vFunc,因此通过类C的虚函数表只能运行得到vFuncC;注释掉类C的vFunc以后,就没有虚函数表的覆盖问题了,那么运行得到vFunB了。
第二种特性:就是用基类的指针指向派生类对象的地址,来调用派生类中的同名的虚函数,基类指针指向哪一个对象的地址就调用哪一个对象的虚函数,同样也满足热性一,就是如果派生类中没有重写基类同名的虚函数的话,无论基类指针指向派生类对象,还是会调用基类的同名虚函数,其实本质上就是派生类会继承基类的虚函数表,基类指针指向派生类的意思只能是基类指针指向派生类中的基类部分,因此理解虚函数表示理解虚函数表的根本。
谢谢阅读,请指正。