虚函数主要作用就为了,通过基类指针访问派生类定义的函数。通过继承和虚函数实现面向对象的多态性。
虚函数语法定义:
用关键字virtural,在成员函数前加virtural就可以,代表此函数为虚函数。
1 |
virtual 成员函数 |
虚函数的实际作用:
虚函数作用记住这点:用基类指针可以控制派生类函数。
写个实际例子来说明。
比如圆形、方形、线等,它们都有draw这个函数,都是从BaseGraphics类继承而来,现在要调用它们的draw函数。我写两个版本一个是虚函数,一个是普通的调用,大家看过后应该理解会更深刻。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
// 梁笔记 // https://zouzhongliang.com #include <iostream> #include <ctime> using namespace std; class BaseGraphics{ private: public: BaseGraphics(){} virtual ~BaseGraphics(){ cout<<"BaseGraphics类析构函数"<<endl; } virtual void draw(){ cout<<"BaseGraphics类draw函数"<<endl; } }; class circle : public BaseGraphics{ private: public: circle(){} virtual ~circle(){ cout<<"circle类析构函数"<<endl; } virtual void draw(){ cout<<"circle类draw函数"<<endl; } }; class square : public BaseGraphics{ private: public: square(){} virtual ~square(){ cout<<"square类析构函数"<<endl; } virtual void draw(){ cout<<"square类draw函数"<<endl; } }; class line : public BaseGraphics{ private: public: line(){} virtual ~line(){ cout<<"line类析构函数"<<endl; } virtual void draw(){ cout<<"line类draw函数"<<endl; } }; int main() { cout<<"普通调用画函数"<<endl; circle* pcir = new circle(); square* psqu = new square(); line* pline = new line(); pcir->draw(); psqu->draw(); pline->draw(); delete pcir; delete psqu; delete pline; cout<<endl; cout<<"虚函数多态方式调用函数"<<endl; BaseGraphics* pbaseGrap[3] = {new circle(),new square(),new line()}; for(int i =0;i<3;i++){ pbaseGrap[i]->draw(); } for(int i =0;i<3;i++){ delete pbaseGrap[i]; } return 0; } |
调用输出结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
普通调用画函数 circle类draw函数 square类draw函数 line类draw函数 circle类析构函数 BaseGraphics类析构函数 square类析构函数 BaseGraphics类析构函数 line类析构函数 BaseGraphics类析构函数 虚函数多态方式调用函数 circle类draw函数 square类draw函数 line类draw函数 circle类析构函数 BaseGraphics类析构函数 square类析构函数 BaseGraphics类析构函数 line类析构函数 BaseGraphics类析构函数 |
可以看出以上代码用虚函数和不用虚函数都可以实现,哪样虚函数有什么用??估计好多人会问??
1.BaseGraphics基类设计成虚类可以让后面继承的类有多态的可能,可以实现自己的draw函数
2.更好的分离代码,比如在设计时就可以先写好调用draw()函数,而不用考虑实际调用哪个类的draw(),这个就是动态绑定。
大家还可能在上面代码中看到了析构函数也都定义成了虚函数,这是为什么?注意点
如果基类析构函数不定义成虚函数,析构时将无法调用派生类的析构函数。
如果还不明白,大家也可以做下测试,将代码复制后,将基类析构函数去掉virtual运行下就会发现问题,也就是上面讲的哪句话的意思。