C++多态定义
C++中的多态分为静态多态和动态多态两种。
静态多态在编译阶段实现,其原理是由函数重载实现,通过不同的实参调用其相应的同名函数。
动态多态通过虚函数实现。
动态多态的两个必要条件:
1. 必须通过基类的指针或者引用调用
2. 被调用的必须是虚函数,且在派生类中实现了该函数的重写(只有虚函数才有重写这个概念)
class Person{
public:
virtual void buyCar(){
std::cout<<"buy sedan car"<<std::endl;
}
};
class boss::public Person{
public:
virtual void buyCar(){
std::cout<<"buy suv car"<<std::endl;
}
}
int main(){
Person p;
Boss b;
Person &tmp1 = p;
Person &tmp2 = b; //tmp2为基类Person对派生类boss的引用
Person *tmp3 = &b; //tmp3为基类Person指向派生类student的指针
tmp1.buyCar();
tmp2.buyCar();
tmp3.buyCar();
}
什么是通过基类的指针或者引用调用?
使用基类型的指针或者引用
虚函数的重写:
首先明确什么是虚函数,virtual修饰的成员函数称为虚函数(友元函数不属于成员函数)
重写的定义: 派生类中的虚函数与基类中虚函数满足函数名、参数、返回值均相同,叫做重写(覆盖)
案例中派生类中的buyCar()即完成了对基类同名虚函数的重写。
构成重写的函数都应是虚函数,即使用virtual修饰的成员函数,同时还要满足三同(函数名、返回值、参数)
多态的原理:
首先介绍虚函数表,在定义了虚函数的类中,都会有一个虚函数表指针,指向该类的虚函数表,虚函数的表指针会在构造函数初始化列表进行初始化,当派生类继承基类时,会继承基类的虚函数表(本质是函数指针数组);如果在派生类中实现了重写,那么派生类中的虚函数表会使用重写后函数的地址覆盖原地址。
总结虚函数表的生成过程,即:
1.先将基类中的虚表内容拷贝一份到派生类虚表中。
2.如果派生类重写了基类中某个虚函数,用派生类自己的虚函数覆盖虚表中基类的虚函数。
3.派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类虚表的最后。
注意:进行切片操作时,不会对虚函数表进行切片。这就导致,如果使用基类的对象调用函数,基类中的虚表仍是父类的虚表,无法实现多态。(基类的虚函数表指针会在初始化列表初始化,初始化后指向基类的虚表)
虚函数相关可参考:
https://blog.csdn.net/qq_32283903/article/details/124997617?spm=1001.2014.3001.5502