一.多态概念
- 多态:一词最初来源于希腊语,意思是:多种形态。
- 多态分为静态多态和动态多态。静态多态分为函数重载和泛型编程。动态多态是通过虚函数来实现的。
- 静态多态(叫静态绑定或早绑定):编译器在编译期间完成的,,编译器可以根据函数实参的类型(可能会进行隐式的类型转换)注意:宏不是静态多态,宏是在预处理阶段完成的
- 动态多态(又叫动态绑定或者晚绑定):在程序执行期间判断所引用对象的实际类型根据其实际类型调用相应的方法。
动态绑定的条件
- 必须是虚函数。
- 必须通过基类类型的指针或者引用调用虚函数。
纯虚函数:在成员函数的形参后面写上=0,则成员函数为纯虚函数。包含纯虚函数的类叫做抽象类(也叫接口类)。抽象类不能实例化出对象。
纯虚函数在派生类中重新定义以后,派生类才能实例化出对象
重写的概念:
怎么才能构成重写?
- 一个在基类一个在派生类。
- 在基类的必须为虚函数,在派生类中重写时函数的原型必须一样(包括返回值,函数的名字以及形参列表),
协变除外
协变:
- 若为基类 -> 返回基类的指针或者引用。
- 若为派生类 -> 返回派生类的指针或者引用。
哪些函数不可以写成虚函数?
1.构造函数 2.拷贝构造函数 3.静态成员函数 4.友元函数 5.赋值运算符重载函数可以写成虚函数,但是最好不要这么做,使用的时候容易混淆- 如果类中有虚函数。那么最好将析构函数写成虚函数。
二.用代码验证有关虚函数的一些理论
1.只要类中有虚函数,编译器就会自动合成一个构造函数,并且改写构造函数,将对象的前四个字节放入虚表的地址。虚表中放着每一个虚函数的地址。
若下代码:
#include<iostream>
using namespace std;
class Base
{
public:
virtual void Funtest1()
{
cout<<"Base::Funtest1()"<<endl;
}
virtual void Funtest2()
{
cout<<"Base::Funtest2()"<<endl;
}
virtual void Funtest3()
{
cout<<"Base::Funtest3()"<<endl;
}
void Funtest4()
{