虚函数在基类和子类中都存在时,调用情况分析

来源:互联网 发布:淘宝懒人装修 编辑:程序博客网 时间:2024/05/01 19:04

首先,给出基类animal和子类fish

//==============================================================//           animal.h//// begin   : 2012-06-30// author  : zwq// describe: 非虚函数情况下,将子类指针赋给积累指针,验证最终调用// 基类函数还是子类函数。//==============================================================#ifndef ANIMAL_H#define ANIMAL_H//===============================================================////  animal// 动物基类////===============================================================class animal{public:void breathe();// 非虚函数virtual void eat(); // 虚函数};//===============================================================////       animal// 鱼类,集成于动物基类////===============================================================class fish : public animal{public:void breathe();// 非虚函数void eat();// 虚函数};#endif
#include "StdAfx.h"#include <iostream>#include "Animal.h"using namespace std;//===============================================================////  animal// 动物基类////===============================================================void animal::breathe(){cout << "animal breathe" << endl;}void animal::eat(){cout << "animal eat" << endl;}//===============================================================////       animal// 鱼类,继承于动物基类////===============================================================void fish::breathe(){cout << "fish bubble" << endl;}void fish::eat(){cout << "fish eat" << endl;}

二.基类animal指针赋给子类fish指针,虚函数调用分析
int main(int argc, char* argv[]){ExamAnimalVirtualFunc();return 0;}void ExamAnimalVirtualFunc(){// 将基类指针直接赋给子类指针,需要强制转换,C++编译器不会自动进行类型转换// 因为animal对象不是一个fish对象fish* fh1;animal* an1 = new animal;// 强制类型转换fh1 = (fish*)an1;// eat()函数为虚函数// 调用基类的eat()fh1->eat();delete an1;an1 = NULL;}

将基类指针经过强制转换成子类指针后,由于eat()函数是虚函数,fish类的指针fh1调用的函数eat()实际上是基类的函数eat()。输出结果如下:分析,虽然fish类的指针fh1调用了函数eat(),但是,由于fish类的指针fh1是由基类指针强制转换后得到的,所以在运行时,依据对象创建时的实际类型来调用相应的函数。(迟绑定技术)


二.子类fish指针赋给基类animal指针,虚函数调用分析

int main(int argc, char* argv[]){ExamAnimalVirtualFunc();return 0;}void ExamAnimalVirtualFunc(){// 将子类指针直接赋给基类指针,不需要强制转换,C++编译器自动进行类型转换// 因为fish对象也是一个animal对象animal* pAn;fish* pfh = new fish;pAn = pfh;// eat()函数为虚函数// 调用子类的eat()pAn->eat();delete pfh; pfh = NULL;}

将子类指针转换成基类指针后,由于eat()函数是虚函数,animal类的指针pAn调用的函数eat()实际上是子类的函数eat()。输出结果如下:


分析,虽然animal类的指针pAn调用了函数eat(),但是在运行时,依据对象创建时的实际类型来调用相应的函数。(迟绑定技术)四. 结论
虚函数在基类和子类中都存在时,依据指针创建时的实际类型来调用相应的函数。
即;new调用时用的哪个类,就用哪个类的虚函数。