面试题-C++-菱形继承-继承&组合-多态-重载&重写&重定义

Posted 天津 唐秙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试题-C++-菱形继承-继承&组合-多态-重载&重写&重定义相关的知识,希望对你有一定的参考价值。

面试题-C+±菱形继承-继承&组合-多态-重载&重写&重定义

  
1.什么是菱形继承,菱形继承的问题是什么?什么是菱形虚拟继承?如何解决数据冗余和二义性的?
  存在四个类,分别是person,student,teacher,assistant,student和teacher分别继承自person,assistant同时继承student和teacher,这种现象就是菱形继承,更深层次的说,assistant内部维护了两份person的成员变量,一份来自student,一份来自person,菱形继承是一种特殊的多继承。
  因为维护了两份person的成员变量,因此,在使用的时候,不知道是使用的来自teacher还是student,因此会存在数据冗余和二义性的问题。
  在继承体系中使用virtual关键字,虚拟继承可以解决菱形继承二义性和数据冗余问题。
在这里插入图片描述
  通过内存对象成员模型,如果我们不用virtual,看到的如上图,person在student和teacher中各有一份,_majorCourse在最下面,如果使用virtual那么会产生在a的内部还有有一个person,这个person同时属于student也属于teacher,在student和teacher的内部分别有一个指向person的虚基表指针,指向了一张表,这两个表叫做虚基表。虚基表中存的是偏移量,通过偏移量可以找到person。
在这里插入图片描述
在这里插入图片描述
2.继承和组合的区别?什么时候用继承?什么时候用组合?
  public继承是一种is-a的关系,也就是说每一个派生类对象都是一个基类对象,组合是一种has-a的关系,假设B组合了A,每一个B对象中都有一个A对象,继承一定程度上破坏了基类的封装性,基类的改变对于派生类有很大的影响,派生类和基类间的依赖关系很强,耦合度很高。并且这种通过派生类的方式的复用通常被称为白箱复用(white-box reuse)。对象通过组合来获得更多功能,要求被组合的对象有良好定义的接口,这种复用风格称为黑箱复用,组合类之间没有很强的依赖关系,耦合度低,如果同时能使用继承和组合,优先使用组合。

3.什么是多态?
  在不同的继承关系中的类对象,去调用同一个函数,产生不同的行为。多态有两个构成条件,第一,必须通过基类的指针或者引用调用虚函数,第二,被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写。

4. 什么是重载,重写(覆盖),重定义(隐藏)?
  重载,要求两个函数在同一个作用域,函数名相同,参数的个数或者是类型不同,目的是相同的函数通过传递进来参数的不同,做出不同的处理。
  重写,也叫做覆盖,两个函数分别处于基类和派生类当中,派生类的函数可以对基类中的函数进行重写,要求函数名、参数。返回值都必须相同,并且两个函数必须都是虚函数,这里面存在两个例外,第一个是协变,基类与派生类虚函数返回值类型不同。协变是派生类重写基类的虚函数时,与基类虚函数返回值类型不同,派生类和基类都是返回自身类型的指针或者是引用,第二个是析构函数的重写,基类与派生类析构函数的名字不同,如果基类的析构函数为虚函数,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同,但是编译器其实做了特殊处理,编译后的析构函数的名字统一为destructor。
  重定义,两个函数分别在基类和派生类当中,两个函数的名字相同,如果两个基类和派生类的同名函数不构成重写,就是重定义。重定义里面存在同名隐藏问题,如果派生类重定义了基类中的函数,那么基类中的其他同名函数但是参数不同的函数将无法再通过派生类构造的对象去调用,如果派生类中没有重定义,就可以调用。

以上是关于面试题-C++-菱形继承-继承&组合-多态-重载&重写&重定义的主要内容,如果未能解决你的问题,请参考以下文章

类的继承派生组合菱形的继承多态

C++多态

C++-继承-菱形继承-菱形虚拟继承-虚函数表

C++--多态

Python之面向对象的组合多态菱形问题子类中重用父类的两种方式

C++--多态