二义基类 在使用多重继承的时候要考虑的一点就是两个或多个父类之间会产生名字二义性。所以, 在实际进行时,在子类中应该明确指名将要调用那个父类的方法。 exp: 实现一个菱形继承关系:解决的方法是Animal类为虚基类 class Animal { public: virtual void eat( )=0; }; class Bird:public Animal { public: virtual void bark( ){cout<<"Woof!/n";} virtual void eat( ){cout<<"the dog has eaten./n";} }; class Dog:public Animal { public: virtual void chirp( ){cout<<"Chrip!/n";} virtual void eat( ){cout<<"the bird has eaten./n";} }; class DogBird:public Dog,public Bird { public: virtual void eat( ) { Dog::eat( ); //存在二义性的时候,要显示指明调用方法 } }; 解决二义性问题,我们可以使用抽象基类和虚基类两种方法。 1、 抽象基类:超类可以作为抽象基类,把其中的各个子类共有的方法定义成纯虚函数,使其函数体为空即可。 因为其函数体为空,所以在上面的菱形层次上其孙子类调用eat()方法的时候就不会由于是采用Dog的eat继承Ainimal的eat还是使用 Bird的eat继承Ainimal的eat产生歧义。 2、 虚基类:在类继承的时候使用virtual关键字修饰被继承类即可。 虚基类会保证所有的子类中每个方法或成员只有一个副本存在。 ex: class Animal { public: virtual void eat( )=0; virtual void sleep(){cout<<"zzz..../n";} }; class Bird:public virtual Animal { public: virtual void bark( ){cout<<"Woof!/n";} virtual void eat( ){cout<<"the dog has eaten./n";} }; class Dog:public virtual Animal { public: virtual void chirp( ){cout<<"Chrip!/n";} virtual void eat( ){cout<<"the bird has eaten./n";} }; class DogBird:public Dog,public Bird { public: virtual void eat( ) { Dog::eat( ); //存在二义性的时候,要显示指明调用方法 } }; int main(int argc,char** argv) { DogBird myConfusedAinimal; myConfusedAinimal.sleep(); //not ambiguous because animal is virtual } 注意: 在类的继承中,虚基类是避免二义性的一个好方法。唯一的缺点是很多C++程序员并不熟悉这个概念。