博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
虚基类
阅读量:5972 次
发布时间:2019-06-19

本文共 1329 字,大约阅读时间需要 4 分钟。

如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。

当一个类D在多重继承时,D的多个基类B、C,又都继承一个基类A。那么,D类的成员中会有2份相同的A的成员。

为了避免产生二义性,即让D类中的成员只有一份A的成员,要用虚基类实现。

C++提供虚基类(virtual base class )的方法,使得在继承间接共同基类时只保留一份成员。

现在,将类A声明为虚基类,方法如下

class A//声明基类A{…};class B :virtual public A//声明类B是类A的公用派生类,A是B的虚基类{…};class C :virtual public A//声明类C是类A的公用派生类,A是C的虚基类{…};

注意: 虚基类并不是在声明基类时声明的,而是在声明派生类时,指定继承方式时声明的。因为一个基类可以在生成一个派生类时作为虚基类,而在生成另一个派生类时不作为虚基类。经过这样的声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次。需要注意: 为了保证虚基类在派生类中只继承一次,应当在该基类的所有直接派生类中声明为虚基类。否则仍然会出现对基类的多次继承。

2、虚基类的初始化如果在虚基类中定义了带参数的构造函数,而且没有定义默认构造函数,则在其所有派生类(包括直接派生或间接派生的派生类)中,通过构造函数的初始化表对虚基类进行初始化。例如

class A//定义基类A{   A(int i){ } //基类构造函数,有一个参数};class B :virtual public A //A作为B的虚基类{   B(int n):A(n){ } //B类构造函数,在初始化表中对虚基类初始化};class C :virtual public A //A作为C的虚基类{   C(int n):A(n){ } //C类构造函数,在初始化表中对虚基类初始化};class D :public B,public C //类D的构造函数,在初始化表中对所有基类初始化{   D(int n):A(n),B(n),C(n){ }};

注意: 

在定义类D的构造函数时,与以往使用的方法有所不同。规定: 在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化。C++编译系统只执行最后的派生类对虚基类的构造函数的调用,而忽略虚基类的其他派生类(如类B和类C) 对虚基类的构造函数的调用,这就保证了虚基类的数据成员不会被多次初始化。
温馨提示:使用多重继承时要十分小心,经常会出现二义性问题。许多专业人员认为:不要提倡在程序中使用多重继承,只有在比较简单和不易出现二义性的情况或实在必要时才使用多重继承,能用单一继承解决的问题就不要使用多重继承。也是由于这个原因,有些面向对象的程序设计语言(如Java,Smalltalk)并不支持多重继承。

参考:www.cnblogs.com/yiranlaobaitu/p/3764422.html

转载于:https://www.cnblogs.com/htj10/p/10191070.html

你可能感兴趣的文章
定制转场动画ControllerTransitionAnimation
查看>>
Django中的ORM
查看>>
iOS开发UI篇—Quartz2D使用(图片剪切)
查看>>
spring学习笔记(20)数据库事务并发与锁详解
查看>>
关于Simple_html_dom的小应用
查看>>
鲁肃:蚂蚁金服的三个梦想
查看>>
【springmvc+mybatis项目实战】杰信商贸-27.POI由HSSF升级为XSSF
查看>>
数学常数e的含义
查看>>
Spring Boot MyBatis 通用Mapper插件集成
查看>>
Django跟Bootstrap3体验以及相比框架提问
查看>>
APM基础小记
查看>>
Omi 6.0 - Store 的设计哲学
查看>>
福利 | 20张2019年蓝牙大会通票免费领
查看>>
XSwitch - 一个解决本地开发请求转发的浏览器插件
查看>>
无限循环RecyclerView的完美实现方案
查看>>
Android中的消息机制
查看>>
TCP - 基础
查看>>
前端常用代码示例-1
查看>>
多线程安全-sychronized
查看>>
Amazing tree —— 二叉查找树
查看>>