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