怎么让网站被百度搜到,网站备案周期,泰安人才网招聘网,投标网站怎么做大家好#xff0c;我是苏貝#xff0c;本篇博客带大家了解C的继承#xff08;下#xff09;#xff0c;如果你觉得我写的还不错的话#xff0c;可以给我一个赞#x1f44d;吗#xff0c;感谢❤️ 目录 5.继承与友元6.继承与静态成员7.复杂的菱形继承及菱形虚拟继承8.继… 大家好我是苏貝本篇博客带大家了解C的继承下如果你觉得我写的还不错的话可以给我一个赞吗感谢❤️ 目录 5.继承与友元6.继承与静态成员7.复杂的菱形继承及菱形虚拟继承8.继承的总结和反思9.笔试面试题 5.继承与友元
友元关系不能继承也就是说基类友元不能访问子类私有和保护成员就像父母的朋友不是你的朋友一样
6.继承与静态成员
基类定义了static静态成员则整个继承体系里面只有一个这样的成员。父类静态成员属于当前类也属于当前类的所有派生类因此无论派生出多少个子类都只有一个static成员实例 如果我们想知道A及其派生类实例化了多少对象就可以定义一个static变量 7.复杂的菱形继承及菱形虚拟继承
单继承一个子类只有一个直接父类时称这个继承关系为单继承 多继承一个子类有两个或以上直接父类时称这个继承关系为多继承
多继承的定义如上图的Assistant只需要在原本继承的基础上加逗号和其它基类即可
菱形继承菱形继承是多继承的一种特殊情况。比如助教对老师来说他是个学生对学生来说他是个老师。因此他有学生和老师两个身份就继承了学生类和老师类
菱形继承的问题从下面的对象成员模型构造可以看出菱形继承有数据冗余和二义性后面介绍的问题。
数据冗余在Assistant的对象中Person成员会有两份。 二义性Student和Teacher类都有_name无法明确知道访问的是哪一个 虚拟继承可以解决菱形继承的二义性和数据冗余的问题。如上面的继承关系在Student和 Teacher的继承Person时使用虚拟继承在继承公共的基类时用虚拟继承即只保存1份Person的成员就不会造成数据冗余二义性也就解决了。需要注意的是虚拟继承不要在其他地方去使用。 在上面这种菱形继承中虚拟继承用在菱形的腰部B和C那下图的用在哪呢也是B和Cvirtual放在有公共基类(A)的类中
虚拟继承解决数据冗余和二义性的原理 为了研究虚拟继承原理我们给出了一个简化的菱形继承继承体系再借助内存窗口观察对象成员的模型。
下面是不加虚拟继承的菱形继承 我们可以从内存窗口看出D里面包含2份A的成员会导致数据冗余和二义性。因为类D先继承B再继承C因此D类的对象d中先出现类B的成员再是类C的成员最后是类D的成员。 同理如果类D先继承C再继承B那么D类的对象d中先出现类C的成员再是类B的成员最后是类D的成员。
下面我们加上虚拟继承
我们可以从内存窗口看出D里面只包含1份A的成员不会导致数据冗余和二义性。而且这时的B和C类的成员中都不包含本来有的A类成员并且都存储了一个地址0x00677bdc和0x00677be4机器是小端存储我们来看看这2个地址指向的内容 原来地址指向的空间叫虚基表里存放的是与A的成员的偏移量还有其它的内容这里不做介绍
为什么要存偏移量在切片的时候有用。将d赋值给类B的对象bb就要把D类中B类那部分切来赋值过去可是这里的B类的成员不包括A类的成员因此B类保存的地址就能找到与A类的成员的偏移量就能找到A类的成员才能最终将B类的成员赋值给bb 多继承本身没有问题但有多继承就可能导致菱形继承
总结实践中可以设计多继承但切记不要设计菱形继承因为太复杂容易出现各种问题
问下面哪个选项是正确的
Ap1 p2 p3 Bp1 p2 p3 Cp1 p3 ! p2 Dp1 ! p2 ! p3
答案C
问下面哪个选项是正确的
Ap1 p2 p3 Bp1 p2 p3 Cp2 p3 ! p1 Dp1 ! p2 ! p3
答案C
问下面程序的结果是什么 类D的对象定义时先走初始化列表再走函数体所以”class D”一定在最后。先声明的先走初始化列表D类中先声明的是B类B继承A所以A比B更先声明再声明C最后D。因此A-B-C-D
8.继承的总结和反思
1、 很多人说C语法复杂其实多继承就是一个体现。有了多继承就存在菱形继承有了菱形继承就有菱形虚拟继承底层实现就很复杂。所以一般不建议设计出多继承一定不要设计出菱形继承。否则在复杂度及性能上都有问题。 2、 多继承可以认为是C的缺陷之一很多后来的语言都没有多继承如Java。 3、 继承和组合 组合是什么将一个类如A作为成员变量放在另一个类中如B
public继承是一种is-a的关系。也就是说每个派生类对象都是一个基类对象。组合是一种has-a的关系。假设B组合了A每个B对象中都有一个A对象。
适合is-a的关系如人和学生就用is-a。适合has-a的关系如汽车和轮胎就用has-a。is-a和has-a都可以如链表和栈就用has-a。即优先使用对象组合而非类继承
继承允许你根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言在继承方式中基类的内部细节对子类可见 。继承一定程度破坏了基类的封装基类的改变对派生类有很大的影响。派生类和基类间的依赖关系很强耦合度高。
对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse)因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。组合类之间没有很强的依赖关系耦合度低。优先使用对象组合有助于你保持每个类被封装。
实际尽量多去用组合。组合的耦合度低代码维护性好。不过继承也有用武之地的有些关系就适合继承那就用继承另外要实现多态也必须要继承。类之间的关系可以用继承可以用组合就用组合。
9.笔试面试题
1、 什么是菱形继承菱形继承的问题是什么 2、 什么是菱形虚拟继承如何解决数据冗余和二义性的 3、 继承和组合的区别什么时候用继承什么时候用组合
复用的常见体现 1、 函数逻辑的复用 2、 模板 3、 继承 4、 组合 好了那么本篇博客就到此结束了如果你觉得本篇博客对你有些帮助可以给个大大的赞吗感谢看到这里我们下篇博客见❤️