复习15:类的层次结构

15.1 引言和概述

15.2 多重继承

       使用多重继承可以用多个父类组合出子类。最常见的是继承多个抽象类,即实现多个接口。但使用多重继承也是有风险的,如可能存在歧义性。

15.2.1 歧义性解析

       两个父类中存在相同名字的成员,包括成员变量和成员函数,在子类中使用该名字就需要歧义性解析。有两种方法完成这项工作。

      1. 子类重新定义了这个名字,遮蔽了父类信息,也遮蔽了歧义性。可以通过加上父类限制符的方式访问父类定义的名字。

      2. 子类没有重新定义 这个名字,则需要通过父类限制符指明引用的是哪一个父类成员。       输出结果如下:可以看出使用父类限制符访问的永远是父类中的成员,这里的虚函数不会表现出多态(多态只出现在父类指针指向子类对象的时候)。

15.2.2 继承和使用声明

      如果类C的父类A,B都有名为f的函数,但是他们的参数列表不同,想让他们在C中构成一组重载函数该怎么办呢?如果我们不做任何处理的话,出现在C中的不是一组重载函数,而是一组重名函数!这是因为重载函数的解析不会跨越不同类的作用域。更近一步说,来自不同父类的函数之间的歧义性不能依靠参数类型完成解析。为了达到我们的目的,我们在子类C中使用声明将这些函数引进一个公共的作用域中。例如,       注,在一个类中使用声明所引用的必须是其父类成员,使用指令是不能出现在类定义里的,也不能对一个类使用。

15.2.3 重复的基类

      如果子类的两个父类有共同的父类,则该子类对象中就会有两个“爷爷" 类的对象。这种情况有时候是有意义的,若想只要”爷爷“类的对象,则使用虚基类(也称虚继承)机制。、

15.2.4 虚基类   B和C虚继承自A,这样他们的子类D只包含了A的一个对象。我们称A为虚基类。

15.2.4.1 用虚基类的程序设计

      这里有两个要说明的问题。

      1. 虚基类只有一个对象存在于子类中,则意味着虚基类的构造函数只被调用一次,而且是在构造最终子类时显式或隐式调用它。

      2. 如果虚基类中有虚函数,若多次调用该虚函数,则该虚函数被调用多次,这可能与我们的期望不同。如果我们想要虚基类的函数只调用一次,则只能有程序员实现这样的功能。

15.2.5 使用多重继承

      使用多重继承最多的场合是继承抽象类实现接口。似乎应该把抽象类的子类都做成虚继承的以减少抽象类的重复,但实际上并没有这样的要求。除了历史的原因外,使用虚继承会带来时间和空间的额外,因为需要虚函数表的辅助。

15.2.5.1 覆盖虚基类的函数

      虚基类的子类选择覆盖虚基类一部分的函数,如果他们覆盖没有重叠的部分,则他们可以作为一个子类共同的父亲。如果覆盖有重叠,则要求他们的儿子覆盖重叠的部分,以消除歧义。

15.2.6 补充一点

      考虑如下代码的结果       c++对这种情况未作定义,下面是在VS上测试的结果。这说明了vs采用如下的方式实现:相同的虚基类共享同一个对象,且这个对象为子类的默认成员;非虚基类对象分别有自己的实例,访问他们需要使用父类限制符。

 

15.3 访问控制

15.3.1 保护成员

      这里给出一个建议。应该考虑父类对子类的可见域,给子类太多可见的东西,往往是设计模糊和潜在错误的指示剂。建议尽可能少的使用protected成员变量,使用protected成员函数作为父类给子类的窗口。

15.3.2 对基类的访问

      public派生方式使得子类成为基类的一个子类型(特例),protected和private派生方式用于表示实现细节。protected在子类继续派生子类的情况下非常有用,这使得孙子能够访问到爷爷的东西。private用于将界面进一步具体化。

15.3.2.1 多重继承的访问控制

      在一个派生图中,如果一个名字或者基类可以从多条路径到达,只要有一条路径能够访问它,它就是可以访问的。 15.3.2.2 使用声明和访问控制

      不能使用声明取得更多信息的访问权。在另一方面,如果某种访问可行,允许将访问权授予其他用户。例如       使用声明和private或protected派生结合使用,可以描述一种界面,只将某一个类所提供的一部分呈现出来(有点像数据库中的视图),例如。       15.4 运行时类型信息

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值