C++——多态(虚函数)
多态是面向对象程序设计语言中数据抽象和继承之外的第三个基本特征。
多态的目的就是为了接口重用,也就是说不管传进来的是什么对象,函数都能通过同一个接口调用到适应各自对象的实现方法。
c++支持编译时多态(静态多态)和运行时多态(动态多态),运算符重载和函数重载就是编译时多态,而派生类和虚函数实现运行时多态。
静态多态和动态多态的区别就是函数地址是早绑定(静态联编)还是晚绑定(动态联编)。如果函数的调用,在编译阶段就可以确定函数的调用地址,并产生代码,就是静态多态(编译时多态),就是说地址是早绑定的。而如果函数的调用地址不能编译不能在编译期间确定,而需要在运行时才能决定,这这就属于晚绑定(动态多态,运行时多态)。
申明基类的指针,指向子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同方法,就是多态
父子类转换
对于有父子关系的两个类,子类的指针可以直接赋值给父类
父类子类指针函数调用注意事项
1,如果以一个基础类指针指向一个衍生类对象(派生类对象),那么经由该指针只能访问基础类定义的函数(静态联翩) 2,如果以一个衍生类指针指向一个基础类对象,必须先做强制转型动作(explicit cast),这种做法很危险,也不符合生活习惯,在程序设计上也会给程序员带来困扰。(一般不会这么去定义) 3,如果基础类和衍生类定义了相同名称的成员函数,那么通过对象指针调用成员函数时,到底调用那个函数要根据指针的原型来确定,而不是根据指针实际指向的对象类型确定。
静态多态和动态多态
多态分为两类
-
静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名
-
动态多态: 派生类和虚函数实现运行时多态
静态多态和动态多态区别:
-
静态多态的函数地址早绑定 - 编译阶段确定函数地址
-
动态多态的函数地址晚绑定 - 运行阶段确定函数地址,用来判断传入的结构体的类型再来处理,而不是指针的申明的类型处理。
重载和重写
重载:
在一个类里面,有相同的函数名,不同的函数列表
重写
不同的类里面,而且这两个类存在继承关系
虚函数注意事项
只有类的成员函数才能声明位虚函数,因为虚函数只适用于有继承关系的类对象。
静态成员不能是虚函数,因为静态成员本质并不属于这个类
构造函数无法定义为虚函数
析构函数虚函数
因为只要是使用父类指针来调用子类的成员都需要变成虚函数后才能根据传入的对象类型来处理,所以如果用父类指针来调用子类成员的时候的析构函数也需要用虚函数来处理。
总结:
多态满足条件
-
有继承关系
-
子类重写父类中的虚函数
多态使用条件
-
父类指针或引用指向子类对象
重写:函数返回值类型 函数名 参数列表 完全一致称为重写