1.什么是多态
多态是指不同继承关系的类对象,去调用同一函数,产生了不同的行为
- 必须通过基类的指针或者引用调用虚函数。
- 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。
2.抽象类
在虚函数的后面写上=0,则这个函数为纯虚函数。
包含纯虚函数的类叫做抽象类,抽象类不能实例化出对象。
派生类继承抽象类后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。
3.虚函数表指针
虚表一般情况下是存在代码段(常量区)的。
每一个含有虚函数的类中都至少有一个虚函数表指针。(多继承可能会含有多个虚表指针)
下列代码中Base类实例化出的对象占8(4+4)个字节。
class Base
{
public:
virtual void Func1()
{
cout << "Func1()" << endl;
}
private:
int _b = 1;
};
4.虚函数表
虚函数表本质是一个存虚函数指针的指针数组
派生类的虚表生成步骤:
1.先将基类中的虚表内容拷贝一份到派生类的虚表。
2.如果派生类重写了基类中的某个虚函数,则用派生类自己的虚函数地址覆盖虚表中基类的虚函数地址。
3.派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类虚表的最后。
虚表是在构造函数初始化列表阶段进行初始化的
在多继承关系当中,派生类的虚表生成过程如下:
分别继承各个基类的虚表内容到派生类的各个虚表当中。
对派生类重写了的虚函数地址进行覆盖(派生类中的各个虚表中存有该被重写虚函数地址的都需要进行覆盖)。
在派生类第一个继承基类部分的虚表当中新增派生类当中新的虚函数地址。
5.内联函数不能是虚函数
内联函数的调用是在编译时确定的,与虚函数的运行时绑定机制相冲突
6.重定义(影藏)
重定义(隐藏)是指两个函数分别在基类和派生类的作用域,这两个函数的函数名相同。若两个基类和派生类的同名函数不构成重写就是重定义。
7.构造函数不能是虚函数
因为对象中的虚表指针是在构造函数初始化列表阶段才初始化的,