1.虚函数,在函数前加virtual即可。有虚函数时,父类指针指向父类对象时就会使用父类的成员,指向子类对象时就可以使用子类成员,进而我们引入了多态的概念。
2.多态:父类指针指向子类的对象,通过父类指针调用子类函数,使其具有多种形态。
2.1.实现多态的必要条件:
1.存在继承关系
2.父类中有虚函数
3.在子类中对父类虚函数进行了重写
4.存在父类指针,并通过该指针调用虚函数
2.2.多态的实现原理:
1.父类的虚函数在子类中重写
2.对象的前四个或八个字节是一个虚指针(vptr)
3.所有的虚函数地址组成一个虚函数列表(vTable)(本质:函数指针数组)
4.虚指针指向虚函数列表
5.在子类中重写的虚函数地址会覆盖掉继承来的虚函数列表中的对应函数的地址
6.当调用函数时根据当前虚函数列表,决定执行哪一个具体的函数
2.3.多态的优点表现在它能提高复用性和拓展性,它的缺点体现在空间,效率以及安全性上。
3.纯虚函数,例如:
virtual void show() = 0
包含纯虚函数的类称为抽象类,抽象类不允许实例化,子类中必须对纯虚函数重写。
所有函数都是纯虚函数的类叫作接口类。
在使用多态时我们要注意一个问题,如下
#include<iostream>
using namespace std;class Father
{
public:Father(){cout << "Father" << endl;}~Father(){cout << "~Father" << endl;}
};class Son:public Father
{
public:Son(){cout << "Son" << endl;}~Son(){cout << "~Son" << endl;}
};int main()
{Father* p = new Son;delete p;return 0;
}
当我们执行此段代码
我们会发现它并没有执行子类的析构函数,会造成内存泄露问题。
为解决此问题我们就要在父类中使用虚析构,即可解决问题。
virtual ~Father()
{cout << "~Father" << endl;
}
注:没有虚构造,有虚析构。