何要使用虚基类:
为何避免多层继承中出项多个公共基类所造成的歧义现象
虚基类用法
派生类继承基类时,加上一个virtual关键词则为虚拟基类继承。
在上图程序运行中,我们发现class bass的构造函数只调用了一次,因此obj.a就不会产生二义性了。
问题1:
在这我们要特别留意下obj.a的结果123,为何它不是122也不是124,偏偏是123呢?
构造函数调用的顺序:
从结果可以看出,从最底层派生类grand开始查找,我们发现grand先调用虚基类derive_v的构造函数;对derive_v而言,它同样开始先调用的虚基类base_V函数,即先输出”CONS base_V“,接着调用基类base的构造函数输出"CONS base",再输出"CONS derive_v";接着grand开始调用其基类derive,本应可获得输出结果"CONS base_V","CONS base"但class base_V是虚基类,也就是说明基类优先调用。
由下面的例子我们在进一步说明构造函数调用的顺序
虽然说派生类B和派生类C有一个公共的虚基类,但是两个类是相互独立的因此,另外由于B是优先创造C故调用顺序为A,B,A,C;
接着继续讨论下面的输出结果,我们发现输出中并没有出现类J,这是为何?由最低成派生类D可以看到,D中有两个基类,两个子对象,但是请注意“J*ptr"这仅仅声明了一个指针,而非对象,也就是说D中仅有一个子对象“m”,因此J中的构造函数不会调用也因此输出结果中并没有”J“;回过头来继续看结果,我们发现基类A是最先调用的,而且其被赋值为12,我们继续由最底层派生类D往上看,发现基类B的声明是先于基类C的,也就是说基类B要先于基类C被调用,我们已经知道了基类B有一个虚基类A,也就是虚基类A最先调用。接着我们看派生类D的第二个基类C,对于这个基类我们有结果发现它并没有再一次调用与B共有的虚基类A,而是仅仅调用了它本身的虚构函数,再一次验证了,虚基类只调用一次的结论。