首先引出,我们的新知识点——虚函数(virtual function)。
这是一种什么函数呢?简单来讲,就是一个函数前面用virtual声明的函数,一般形式如下:
virtual函数返回值函数名(形参){函数体}
那它有什么用呢?虚函数的出现,允许函数在调用时与函数体的联系在运行的时候才建立,即所谓的动态联编。那么在虚函数的派生类的运行时候,就可以在运行的时候根据动态联编实现都是执行一个方法,却出现不同结果的效果,就是所谓的多态。这样解决上一节的问题就有了办法。
接下来,我们只需要把基类中的area方法声明为虚函数,那么主函数中无论Point类型的指针还是引用就都可以大胆调用,无用关心类型问题了。因为他们会依据实际指向的对象类型来决定调用谁的方法,来实现动态联编。
代码如下:
/**************************************//Des:C++教程demo//Author:Huang//Copyright:www.dotcpp.com//Date:2017/12/20**************************************/#include<iostream>usingnamespacestd;#definePI3.1415926classPoint{private:intx,y;public:Point(intx=0,inty=0){this->x=x;this->y=y;}virtualdoublearea(){return0.0;}};classCircle:publicPoint{private:intr;public:Circle(intx,inty,intR):Point(x,y){r=R;}doublearea(){returnPI*r*r;}};intmain(){PointA(10,10);cout<<A.area()<<endl;CircleB(10,10,20);cout<<B.area()<<endl;Point*p;p=&B;cout<<p->area()<<endl;Point&pp=B;cout<<pp.area()<<endl;return0;}
修改后编译运行如下:
大家请自行上机实验,体会虚函数及多态的作用。
需要注意的是:
1. 虚函数不能是静态成员函数,或友元函数,因为它们不属于某个对象。
2. 内联函数不能在运行中动态确定其位置,即使虚函数在类的内部定义,编译时,仍将看作非内联。
3. 构造函数不能是虚函数,析构函数可以是虚函数,而且通常声明为虚函数。