问题1>为什么要有虚基类?
多重继承时,当两个基类继承自同一个类时,由此二基类多重派生的类,将包含两个基类的基类
class A;
class B:public A
class C:public A
class D:public B,public C //此时D中将包含两个继承来的A
解决:能否只继承一个A呢?
答案:可以,使用虚基类!!!
class B: virtual public A; //virtual和public顺序无所谓
class C: virtual public A;
此时:
class D: public B, public C ; //将只包含一个继承来的A
至此:虚基类完美解决问题。
问题2>引入了虚基类,是否会带来一些规则上的改变?
答案是肯定的。
改变1> 构造函数规则
非虚基类情况:
class A;
class B:public A;
class C:public B;
C类构造函数----调用B类的构造函数----B类的构造函数调用A类的构造函数
如果是虚基类,这种信息的自动传递将不起作用
class A;
class B: virtual public A; //使用虚基类
class C: virtual public A; //使用虚基类
class BC: public B,public C;
BC(const A &a,int b,int c): B(a,b),C(a,c) //将出错!!!!!
问题:自动传递信息时,将通过2条不同的途径(B、C)将a传递给A对象,(虚基类时,只需要一个对象)
解决:为避免冲突,C++在基类是虚拟的时,禁止信息通过中间类(B、C)自动传递给基类
但:编译器在构造派生对象之前必须要构建基类对象,此时,编译器将调用所需基类A的默认构造函数
问题:如果不想使用默认的构造函数来构造虚基类对象,怎么办???
解决:显示调用虚基类的构造函数
BC(const A &a,int b,int c): A(a), B(a,b),C(a,c) {} //此时大功告成!!!
改变2>使用哪个方法?
问题:
classs A; //A中定义了一个Show()方法;
class B: public A; //B继承A并重新定义了Show()方法;
class C:public A; //C继承A也重新定义了Show()方法;
class BC:virtual public B, virtual public C ; //BC中没有重新定义Show()方法,打算使用继承的Show()方法
最好在BC中重新定义Show()方法,也就是下面的,解决方法2
此时出现问题:
BC bc;
bc.Show(); //BC的两个直接基类B,C都定义了Show()方法,此时使用哪个基类的Show()方法呢?
解决方法1:使用作用域解析操作符澄清意图
BC bc;
bc.B::show(); //使用B类的Show()方法;
解决方法2:在BC中重新定义Show()方法
void BC::show()
{
B::show();
} //这种方式对单继承可行,对多继承不好使,是错误的
//因为它忽略了C组件
补救:
void BC::Show()
{
B::Show(); //B继承自A,调用了一次A类中的Show()方法
C::Show(); //C继承自A,又调用了一次A类中的Show()方法
} 问题: 这将会调用两次A类的Show()方法
解决:定义一个内部的protected 方法只Show自己类中新加的属性,
然后在继承类的Show()方法中组合显示