前言
之前介绍了通过指针和引用来实现多态的方法,接下来将继续学习多态的相关知识
一、多态的定义和实现
1.多态性
多态性是指在不同继承关系的类对象中调用了一个名字相同定义不同的函数,这些函数执行不同但又类似的操作,这样就可以用同一个函数名调用不同内容的函数。
通过之前的例子我们还知道了要想构成多态还需要满足两个条件:
1.调用函数的对象必须是指针或者引用。
2. 被调用的函数必须是虚函数,且完成了虚函数的重写。
2.虚函数
虚函数就是指
在类的成员函数前加virtual关键字的函数
虚函数的重写指的是
派生类中的有一个跟基类中虚函数的函数名、参数、返回值都相同的虚函数,我们就称子类的虚函数重写了基类的虚函数。
二、虚函数与纯虚函数
上面介绍了虚函数,下面来说说纯虚函数,在虚函数的后面写上 = 0,则这个函数为纯虚函数。纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。例如,
virtual void funtion1()=0
1.引入原因
- 为了方便使用多态特性,我们常常需要在基类中定义虚拟函数。
- 在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。
为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。
定义纯虚函数的目的在于,使派生类仅仅只是继承函数的接口。
2.抽象类
抽象类的定义:称带有纯虚函数的类为抽象类。
3.虚函数表
虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的。简称为V-Table。在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证其容真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。
一个含有虚函数的类中至少都有一个虚函数表指针,因为虚函数的地址要被放到虚函数表(虚表)中。
对于派生类的虚表生成有如下的总结:
1.先将基类中的虚表内容拷贝一份到派生类虚表中;
2.如果派生类重写了基类中的某个虚函数,用派生类自己的虚函数覆盖虚表中基类的虚函数;
3.派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类的虚表的最后。