11.16C++虚基类详解

11.16C++虚基类详解

ID:37928376

大小:112.00 KB

页数:5页

时间:2019-06-03

11.16C++虚基类详解_第1页
11.16C++虚基类详解_第2页
11.16C++虚基类详解_第3页
11.16C++虚基类详解_第4页
11.16C++虚基类详解_第5页
资源描述:

《11.16C++虚基类详解》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

1、我们知道,如果一个派生类有多个直接基类,而这些直接基类又有一个共同的基类,则在最终的派生类中会保留该间接共同基类数据成员的多份同名成员。在引用这些同名的成员时,必须在派生类对象名后增加直接基类名,以避免产生二义性,使其惟一地标识一个成员,如:  c1.A::display()在一个类中保留间接共同基类的多份同名成员,虽然有时是有必要的,可以在不同的数据成员中分别存放不同的数据,也可以通过构造函数分别对它们进行初始化。但在大多数情况下,这种现象是人们不希望出现的。因为保留多份数据成员的拷贝,不仅占用较多的存储空间,还增加了访问这些成员时的困难,容易出错

2、。而且在实际上,并不需要有多份拷贝。C++提供虚基类(virtual base class)的方法,使得在继承间接共同基类时只保留一份成员。假设类D是类B和类C公用派生类,而类B和类C又是类A的派生类,如图11.21所示。设类A有数据成员data和成员函数fun;派生类B和C分别从类A继承了data和fun,此外类B还增加了自己的数据成员data_b,类C增加了数据成员data_c。如果不用虚基类,就会在类D中保留了类A成员data的两份拷贝,分别表示为intB::data和intC::data。同样有两个同名的成员函数,表示为voidB::fun(

3、)和voidC::fun()。类B中增加的成员data_b和类C中增加的成员dat_c不同名,不必用类名限定。此外,类D还增加了自己的数据成员data_d和成员函数fun_d。图11.21现在,将类A声明为虚基类,方法如下:.class A //声明基类A.{.//代码.};.class B: virtual public A //声明类B是类A的公用派生类,A是B的虚基类.{.//代码.};.class C: virtual public A //声明类C是类A的公用派生类,A是C的虚基类.{.//代码.};注意:虚基类并不是在声明基类时声明的,而

4、是在声明派生类时,指定继承方式时声明的。因为一个基类可以在生成一个派生类时作为虚基类,而在生成另一个派生类时不作为虚基类。声明虚基类的一般形式为:  class派生类名:virtual继承方式 基类名即在声明派生类时,将关键字virtual加到相应的继承方式前面,经过这样的声明后,当基类通过多条派生路径被一个派生类继承时,该派生类只继承该基类一次,也就是说,基类成员只保留一次。需要注意:为了保证虚基类在派生类中只继承一次,应当在该基类的所有直接派生类中声明为虚基类。否则仍然会出现对基类的多次继承。如果在派生类B和C中将类A声明为虚基类,而在派生类D中

5、没有将类A声明为虚基类,则在派生类E中,虽然从类B和C路径派生的部分只保留一份基类成员,但从类D路径派生的部分还保留一份基类成员。虚基类的初始化如果在虚基类中定义了带参数的构造函数,而且没有定义默认构造函数,则在其所有派生类(包括直接派生或间接派生的派生类)中,通过构造函数的初始化表对虚基类进行初始化。例如.class A //定义基类A.{.A(int i){ } //基类构造函数,有一个参数};.class B :virtual public A //A作为B的虚基类.{.B(int n):A(n){ } //B类构造函数,在初始化表中对虚基类初

6、始化.};.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的构造函数时,与以往使用的方法有所不同。以往,在派生类的构造函数中只需负责对其直接基类初始化,再由其直接基类负责对间接基类初始化。现在,由于虚基类在派生类中只有一份数据成员,所以这份数据成员的初始化

7、必须由派生类直接给出。如果不由最后的派生类直接对虚基类初始化,而由虚基类的直接派生类(如类B和类C)对虚基类初始化,就有可能由于在类B和类C的构造函数中对虚基类给出不同的初始化参数而产生矛盾。所以规定:在最后的派生类中不仅要负责对其直接基类进行初始化,还要负责对虚基类初始化。有的读者会提出:类D的构造函数通过初始化表调了虚基类的构造函数A,而类B和类C的构造函数也通过初始化表调用了虚基类的构造函数A,这样虚基类的构造函数岂非被调用了3次?大家不必过虑,C++编译系统只执行最后的派生类对虚基类的构造函数的调用,而忽略虚基类的其他派生类(如类B和类C)对

8、虚基类的构造函数的调用,这就保证了虚基类的数据成员不会被多次初始化。虚基类的简单应用举例[例11.9]在例1

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。