【C++】C++多态
1.什么是多态
答:(要点)
(1)静多态 早绑定 函数重载、模板(编译时期的多态)
(2)动多态 晚绑定 主要表现在继承中的多态 运行时期确定
详细回答:
C++中多态分为两种,静态多态和动态多态。静态多态主要是指函数重载、模板的多态,在编译阶段就已经确定该调用那个函数、确定模板的参数类型,也称为早绑定;动态多态主要是指在运行期间发生的多多态,也称晚绑定,主要是在继承上的多态,由于子类重写父类的虚函数,即子类的成员方法指针覆盖了父类的成员方法指针,最后使用父类指针或者引用调用虚函数时发生多态。
2.动多态的必须条件,动多态的调用过程
答:
动多态的必须条件:
- 基类必须有虚函数,派生类重写父类虚函数;
- 其次有基类指针或者基类引用指向派生类对象;
- 最后该指针或者引用调用虚函数。
- 对象必须完整(构造之后,析构之前)
动多态的调用过程:
- 指针/引用调用虚函数
- 通过vfptr(虚函数指针)找到vftable(虚函数表)
- 在vftable(虚函数表中)找到对应的函数指针
- 调用该函数指针
3.什么情况下析构函数必须写成虚函数
答:父类指针指向堆上的子类对象,delete父类指针的时候,防止未调用子类的析构函数,父类的析构函数必须写成虚函数。
(基类中最好要有虚函数,防止基类指针指向子类对象时候,指针指向位置不是子类的开始位置—)
4.静态函数、构造函数、析构函数能不能写成虚函数
静态函数:不可以
(1)静态函数不依赖类对象存在,加上virtual没有意义
(2)静态函数没有this指针,通过this指针可以访问虚函数指针,通过虚函数表访问函数指针;
依赖关如下:this -> vfptr -> vftable ->virtual function
构造函数:不可以
- 虚函数的执行依赖于虚函数表。而虚函数表在构造函数中进行初始化,即让vfptr指向正确的虚函数表,而在构造对象期间,虚函数表还未初始化,无法找到构造函数的地址。
- 虚函数是在运行期间确定实际类型的,而构造一个对象的时候必须确定对象的类型(编译期间),产生矛盾。
5.虚函数能不能被处理成内联
答:不能,是否将函数处理成内联取决于编译器,在编译期间是否将函数处理成内联函数(展开后,没有该函数地址,不用进入函数,直接执行函数体),而在运行期间,虚函数的确定需要函数的地址,此时该函数已经没有地址。
6.什么是虚函数表,产生时间,存放位置,什么时候把vfptr写入对象中
答:
虚函数表:就是用来存放虚函数的地址
产生时间:编译期间,存放在.rodata段
构造对象时候将vfptr写入对象。
7.什么是RTTI,RTTI的产生时间和存放位置
RTTI:运行期间类型标识,RTTI是对象类型结构体的一个指针,指向对象类型的结构体;
RTTI在编译时期产生,产生之后将地址写入vftable(虚函数表),存放在.rodata段;
8.类与类的关系
答:
(1)组合关系:一个类是另一个类的一部分
(2)代理关系:一个类的接口是另一个类的接口的一部分
(3)继承关系:一个类是另一个类的一种