多态:
什么是多态?
1.概念:同一事物在不同场景下表现出不同的状态。
多态的例子
2.实现多态的条件
>>基类中必须存在虚函数,派生类必须要对基类中的虚函数进行重写
>>用基类的引用或指针来调用虚函数
表现:基类的指针调用虚函数
在代码运行期间,根据基类指针指向不同子类的对象,来确定实际调用那个类的虚函数
重写:
1.基类中被重写的函数一定是虚函数
2.派生中虚函数必须与基类中虚函数的原型完全相同(返回值类型函数名字(参数列表))
>>协变:基类虚函数返回基类对象的引用或者指针
派生类虚函数返回派生类对象的引用和指针
>>析构函数:函数名字不同
变量的类型:
1.静态类型:声明变量时的类型(非多态)
2.动态类型:变量实际指向(引用)的类型(满足多态条件)。
动态类型的确定在程序运行时,而静态类型在编译阶段。
将虚函数按照其在基类中声明的先后次序放在续表中
编译阶段生成,并且每个包含有虚函数的类只有一份续表(普通的单继承)
派生类续表的构建:
1.先将基类虚表中虚函数拷贝一份到派生类虚表中。
2.如果派生类重写了基类中的虚函数,用派生类自己的虚函数替换相同偏移量位置同名的基类虚函数。
3.将派生类新增加的虚函数按照其在类中的声明次序添加到派生类续表的最后。
1.基类:普通类型的成员函数
2.测试普通基类对象的大小
3.将基类中的普通函数设置成虚函数,测试类对象大小,结果对象中多了4个字节
4.验证4个字节的作用:
通过对象模型-->地址-->指向一个位置:在基类中增加虚函数
初步结论:对象前4个字节指向的位置存放的是虚函数地址
5.验证:打印前4个字节指向位置中的内容
结论:对象前4字节放置续表指针-->虚函数表格(虚表)
6.调整基类中虚函数的次序,结论:基类中虚表的构建原理-->按照虚函数在基类中的声明先后次序存放
7.一个类中如果包含有虚函数-->在编译阶段,编译器生成虚表,一个类的多个对象共享该类的虚表
8.验证派生类虚表的构建过程
>>给个空的派生类:将基类虚表中内容拷贝一份到派生类虚表中
>>在派生类中重写基类的虚函数:使用派生类自己的虚函数替换相同偏移量位置的基类虚函数
>>在派生类中增加新的虚函数:将派生类新增加的虚函数放置在虚表的最后
9.探索多态的调用原理
前提:多态的实现条件必须满足(2个条件)
>>1.不满足--不是多态调用,指针或引用的静态类型来确定调用的函数(编译)
>>2.满足:根据指针或引用的动态类型来确定具体调用那个类的虚函数(在程序运行时才能确定对象的动态类型)
多态的调用步骤:
1.从指针或引用的具体的对象中取虚表的地址
2.传递this指针
3.从虚表中取虚函数的地址
4.调用该虚函数
多态的缺陷:降低程序的运行速度。
虚表是在编译阶段完成的,存放在代码段
多态
最新推荐文章于 2024-10-24 21:54:11 发布