C++多态常见面试题

1.什么是多态

简单点说,就是多种形态,具体就是完成某个行为,当不同的对象去完成时产生的不同形态。多态分为静态多态和动态多态,静态多态一般指的是函数重载,在编译阶段通过函数名修饰规则,不同类型调用不同函数。动态多态指的是在运行阶段父类的指针或者引用通过续表调用不同的虚函数的过程。

2.什么是重载,重写,重定义

  • 函数重载:两个函数在不同作用域,函数名相同,参数不同(个数不同,顺序不同,类型不同)
  • 重写/覆盖:两个函数分别在基类和派生类作用域,且必须都是虚函数,并且两个函数的返回值,函数名,参数相同(协变例外)
  • 隐藏/重定义:两个函数分别在基类和派生类的作用域,函数名相同就构成隐藏(函数名相同的情况下不构成重写就构成隐藏)

3.多态的实现原理

能实现多态的最大功臣可以说是虚函数表了,每个类对象内部有一个续表指针,存储着当前对象内部的虚函数地址。当一个函数符合多态调用的时候,派生类会对从基类继承下来的续表进行重写,重写成父类的函数,此时基类和派生类中同一个函数地址便不一样了。当一个父类的指针或者引用调用该函数时,它会去当前对象续表指针里指向的续表去找虚函数,此时父类的指针或者引用指向基类则调用的函数便是基类的虚函数,指向派生类中则调用的是函数时派生类虚函数,从而当父类的指针或者引用不同父类或子类对象时,便调用不同的函数,完成不同的功能。

4.inline函数可以是虚函数吗?

  • 可以,如果是普通的虚函数,inline函数可以是虚函数。但如果这个函数构成了多态,此时这个虚函数需要放进续表,编译器会忽略inline的这个属性,此时函数便不再具备inline的特性。

5.静态函数可以是虚函数吗?

  • 不可以,静态函数里没有this指针,使用类型::成员函数无法访问虚函数表,所以静态成员函数无法放进虚函数表中。

6.构造函数可以是虚函数吗?

  • 不可以,因为虚函数表指针是在构造函数初始化列表阶段才初始化的

7.析构函数可以是虚函数吗?什么场景下析构函数是虚函数?

  • 可以,并且非常建议把父类的析构函数设置为虚函数,防止产生内存泄漏问题。(class A : public B,B Node* = new A)

8.对象访问普通函数快还是虚函数快

  • 如果是普通调用一样快,如果是多态调用,普通函数快,多态调用要通过续表找地址,会有一定程度的效率损耗。

9.虚函数表是在什么阶段生成的,存在哪里?

  • 在编译阶段生成,虚函数表指针在构造函数初始化列表初始化,存在代码段/常量区

10.C++菱形继承的问题?虚继承的原理

  • C++菱形继承会产生数据冗余和二义性问题。菱形虚拟继承更改了数据模型,把公共的虚基类放在当前对象模型的最下面,同时对象模型里产生了虚基类指针指向虚机表。在这个表中存有当前位置离虚基类的偏移量,通过偏移量和当前位置的地址找到公共的存放虚基类成员变量的地址。

11.什么是抽象类?抽象类的作用?

  • 包含纯虚函数的类是抽象类,抽象类不能实例化对象,所以抽象类强制了子类要对基类的纯虚函数进行重写虚。此外抽象类还体现了接口继承。

你可能感兴趣的:(C++,c++,java,开发语言)