什么是多态?
所谓多态,就是同一个操作,作用在了不同的对象上,就会有不同的解释,进而产生不同的执行结果。使用时,是采用父类指针指向子类对象的方法。其中,重载和重写是常见的实现多态的手段。
什么是重载、重写(覆盖)、重定义(隐藏)?
- 重载就是函数名相同,参数不同,两个函数在同一作用域
- 重写:两个函数分别在子类和父类中,函数名,返回值,参数均相同,函数必须为虚函数
- 重定义也叫隐藏,指的是在继承关系中,子类实现了一个和父类名字一样的函数,(只关注函数名,和参数与返回值无关)这样的话子类的函数就把父类的同名函数隐藏了。隐藏只与函数名有关,与参数没有关系.
多态的实现原理?
虚函数是类的成员函数,存在存储虚函数指针的表叫虚函数表,虚函数表是一个存储类成员函数指针的数据结构,在编译时由编译器自动产生,virtual成员函数会被编译器放入虚函数表中,当存在虚函数时,每个对象中都有一个指向虚函数的指针,每个指针都指向调用它的地方,当子类调用虚函数时,就会去虚表里面找自己对应的函数指针,从而实现谁调用,实现谁,从而实现多态。
inline函数可以是虚函数吗?
不能,因为inline函数没有地址,无法把地址放到虚函数表中。
静态成员可以是虚函数吗?
不能,因为静态成员函数没有this指针,使用类型::成员函数的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表。
构造函数可以是虚函数吗?
不能,因为对象中的虚函数表指针是在构造函数初始化列表阶段才初始化的。
析构函数可以是虚函数吗?什么场景下析构函数是虚函数?
可以,并且最好把基类的析构函数定义成虚函数。因为析构函数在汇编时会将所有的析构函数转化为Destructed,调用谁,析构谁,若析构函数不是虚函数,可能存在在子类析构时,继承的父类没有析构,产生内存泄露,所以建议都写成虚函数。
对象访问普通函数快还是虚函数更快?
首先如果是普通对象,是一样快的。如果是指针对象或者是引用对象,则调用的普通函数快,因为构成多态,运行时调用虚函数需要到虚函数表中去查找。
虚函数表是在什么阶段生成的,存在哪的?
虚函数表是在编译阶段就生成的,vs一般情况下存在代码段(常量区)的。
C++菱形继承的问题?虚继承的原理?
菱形继承:一个子类,继承两个父类,容易导致二义性,调用不明确,比如下图,student,和teacher都继承了person,,而他两又都被assistant继承,如果调用person的函数,就不知道从哪里调上去的,产生二义性。且存了两份person,造成数据冗余。
虚继承的原理:通过虚基表存了三者共有的指针存了一份,所以虚继承以后,只会初选一份。
什么是抽象类?抽象类的作用?
类中所有成员均为虚函数,虚函数不能实例化,抽象类强制重写了虚函数,另外抽象类体现出了接口继承关系。