//二义性#include<iostream>usingnamespacestd;classBase{public:Base(){cout<<"Basecalled..."<<endl;}voidprint(){cout<<"Base::print()"<<endl;}};classSub{public:Sub(){cout<<"Subcalled..."<<endl;}voidprint(){cout<<"Subprint...."<<endl;}};classChild:publicBase,publicSub{public:Child(){cout<<"Childcalled..."<<endl;}};intmain(void){Childc;//c.print();报错,这里c类中的有两个print()函数,它们的地位相同c.Base::print();c.Sub::print();return0;}




//砖石继承,二义性

#include<iostream>usingnamespacestd;intgFlag=0;classBase{public:Base(){cout<<"Base::Base()"<<++gFlag<<endl;}voidprint(){cout<<"Base::print()"<<endl;}};classMid1:publicBase{public:Mid1(){cout<<"Mid1:Mid1()"<<endl;}};classMid2:publicBase{public:Mid2(){cout<<"Mid2:Mid2()"<<endl;}};classChild:publicMid1,publicMid2{public:Child(){cout<<"Child:Child()"<<endl;}};intmain(void){Childd;//d.print()<<endl;报错,这样使用会产生二义性d.Mid1::print();//okd.Mid2::print();//okreturn0;}

Base::Base()1
Mid1::Mid1()
Base::Base()2
Mid2::Mid2()
Child::Child()

在实例化,Child对象时,先会调用Mid1和Mid2构造函数,Mid1和Mid2分别继承与Base,所以

Base最终被调用了两次.


虚继承

#include<iostream>usingnamespacestd;intgFlag=0;classBase{public:Base(){cout<<"Base::Base()"<<++gFlag<<endl;}voidprint(){cout<<"Base::print()"<<endl;}};classMid1:virtualpublicBase{public:Mid1(){cout<<"Mid1::Mid1()"<<endl;}};classMid2:virtualpublicBase{public:Mid2(){cout<<"Mid2::Mid2()"<<endl;}};classChild:publicMid1,publicMid2{public:Child(){cout<<"Child::Child()"<<endl;}};intmain(void){Childd;d.print();return0;}

Base::Base()1
Mid1::Mid1()
Mid2::Mid2()
Child::Child()
Base::print()

虚继承,会共享子类通过虚继承的基类的内存,Mid1调用实例化了一次Base,Mid2构造时,就没有再次

实例化Base,Mid1和Mid2共享基类Base的内存.

虚继承,解决了二义性问题,也节省了内存.