调用父类的example(),无法实现多态性.
所以C++引入了虚函数概念,根据指针指向的对象类型,来执行不同类的同名覆盖成员函数,实现不同的形态
定义: 在父类成员函数的返回值前面,通过virtual关键字声明,这样便能访问子类中的同名成员函数了
接下来将上个示例的父类成员函数example()改写为虚函数:
virtual void print() //将父类的成员函数定为虚函数
{
cout<<"class Parent"<<endl;
}
运行打印:
class Parent
class Child
SIZEOF Parent:8
SIZEOF Child:12
可以发现,父类和子类的长度都增加了4字节,这4个字节就是用来指向“虚函数表”的指针,编译器便会更据这个指针来执行不同类的虚函数,实现多态性.
虚析构函数
-在使用基类指针指向派生类对象时用到
-通过基类析构函数可以删除派生类对象
示例
#include <iostream>
using namespace std;
class Base
{
public:
Base()
{
cout << "Base()" << endl;
}
virtual ~Base()
{
cout << "~Base()" << endl;
}
};
class Derived : public Base
{
public:
Derived()
{
cout << "Derived()" << endl;
}
~Derived()
{
cout << "~Derived()" << endl;
}
};
int main()
{
Base* p = new Derived();
// ...
delete p;
return 0;
}
运行打印:
Base()
Derived()
~Derived()
~Base()
可以发现,由于基类的析构函数是虚函数,所以我们delete基类指针时,派生类也跟着调用了析构函数,从而避免了内存泄漏,也能满足使用dynamic_cast强制转换了
一般而言,虚构造函数只有在继承下才会被使用,单个类是不会使用虚构函数的,因为虚函数表会产生额外的空间
注意:构造函数不能成为虚函数,因为虚函数表是在构造函数执行后才会进行初始化