C++编程入门(二) 互动版

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器

动态联遍

上面的函数func,如何才能做到执行时,看参数是Rectangle类的对象,就执行Rectangle类的area实现;看参数是Circle的对象,就去执行Circle类的area实现呢?这就要用到动态联遍。实现方法是将area函数声明为虚函数。area成为虚函数之后,编译器在编译到func中调用的area时,就不会使用静态联遍了,而是运行时动态联遍,动态的选择执行哪个实现。再看下面的代码:

#include <iostream>
using namespace std;
class Rectangle
{
    public:
        //构造函数
        Rectangle(double a,double b){h=a;w=b;}
        virtual double area(){return h\*w;}
    private:
        double h,w;
};
class Circle:public Rectangle
{
    public:
        //构造函数
        Circle(double a,double b,double c):Rectangle(a,b){r=c;}
        virtual double area(){return 3.14\*r\*r;}
    private:
        double r;
};
void func(Rectangle &rec)
{
    cout<<rrec.area()<<endl;
}
void main()
{
    Rectangle r1(2,3);
    Circle c1(4,5,1);
    func(r1);
    func(c1);
}

只更改了两行:第7行和第15行。在area声明的最前面加关键字virtual。这样编译器就知道了,不能把func中对area的调用都去找Rectangle中的实现,要动态的根据参数类型去找相应实现。输出为:

6

3.14

注意两点:

1.函数func的参数是引用或者指针是,才采取动态联遍。上例中如果是void func(Rectangle rec),那么还是静态联遍。

2.父类中已经说明area是虚函数了,子类中可以省略virtual,也就是第15行的virtual可以不写,效果一样的。

3.析构函数也可以被声明为虚函数,叫做虚析构函数。