如果一个类由两个或多个基类派生,即多重派生,且在不同的基类中具有名字相同的
公有成员或保护成员,此时若在派生类中使用这类同名成员,就会出现不唯一,产生二义性的错误,这种情况称为冲突。解决方法:
1)避免同名。
2)使用作用域运算符来限定所访问的成员是属于哪一个基类的。格式: <类名>::<成员名> 即
多继承情况下二基类间成员重名时,按如下方式进行处理:对子类而言,不加类名限定时默认为是处理子类成员,而要访问父类重名成员时,则要通过类名限定。
3)注意:对于连续派生时,即派生类作为基类派生出新的类时,作用域运算符不能连续使用,即下列形式不允许: CName1::Cname2::Cnamen。
例3 冲突的程序示例 # include
{protected : int x ; public:
A (int a ) {x=a ;} void Show (void )
{cout<<”x=”< { protected : int x ; public : B ( int a ){x=a ;} void Show(void ) {cout<<”x=”< class C :public A , public B int y ; public : C (int a , int b ) :A(a) ,B (b) { } void Setx(int a){x=a ;} //A,冲突,二义性,编译时,不知是A的x,还是B的x. //改为:{A::x=a ;} void Sety(int b){y=b ;} int Gety(void ) {return y ;} }; void main (void ) { C c1 (10 ,100) 26 c1.Show ( ) ; //B,冲突,二义性,编译时,不知是A的show,还是B的show. //改为;c1.B::Show(); } 执行结果: x=100 Press any key to continue 例4 具有形如图11.4的类结构的冲突问题 3)注意:对于连续派生时,即派生类作为基类派生出新的类时,作用域运算符不能连续使用,即下列形式不允许: CName1::Cname2::Cnamen。 # include 类B1 类B2 class B1 {protected : int x ; public : 类D1 类D2 void Show ( ) {cout<<”x=”< class B2 类C {protected : int x ; 图11.4 public: void Show ( ) {cout<<”x=”< class D1 :public B1 { }; class D2 :public B2 { } ; class C::public D2 , public D1 {public : void SetX1(int a){D1:::B1::x=a ;} //A错误,域运算符不能连续使用,改为:{D1::x=a ;} void SetX2(int a){D2::x=a ;} //B 正确,或为B2::x=a ; }; void main (void ) { C c; c.SetX1(2) ; c.D1::B1::Show() ; //C 错误,域运算符不能连续使用,改为c.D1::Show() c.SetX2(3) ; c.D2::Show() ; //D 正确,或c.B2::Show() ; } 执行结果为: x=2 x=3 27 8.4.3 多级混合继承(非虚拟继承)包含两个基类实例情况的处理 类CA 类CB1 类CD 类CB2 图 多级混合继承 如上图,若CA有成员数据a和成员函数show(),则CB1和CB2 都各继承了一个ah和show(),而类CD继承了CB1和CB2,所以类CD拥有继承来的两个a 和两个show(),如果创建 CD的对象CDobj,则CD类的成员函数引用或通过CD的对象引用CDobj.a 和CDobj. show()时会产生二义性。 解决方法: 1)使用作用域运算符来限定所访问的成员是属于哪一个基类的。格式: <类名>::<成员名> 如上例可以:CDobj.CB1::a 和 CDobj.CB2::a CDobj. CB1::show() 和CDobj. CB2::show() 例5 #include class B:public A { public: int b; B(int x):A(x-1){b=x;} }; class C:public A { public: int c; C(int x):A(x-1){c=x;} }; class D:public B,public C { public: int d; D(int x, int y, int z):B(x+1),C(y+2){d=z;} void showall() { 28 cout<<\ //在类D定义范围内,要通过类名限定来指定 //访问两个类A实例中的哪一个 cout<<\ cout<<\ //b、c、d不重名,具有唯一性 } }; void main() { D Dobj(101, 202, 909); Dobj.showall(); cout<<\ cout<<\ //访问类D的从C继承而来的a cout<<\} /*C::a=203 B::a=101 b,c,d=102, 204, 909 ------------------- Dobj.C::a=203 Dobj.B::a=101 */ 2)通过虚基类。见下节。 上述多级混合继承关系应用例举: 例1. 类A--人员类; 类B--学生类; 类C--助教类; 类D--学生助教类。 例2. 类A--人员类; 类B--学生类; 类C--工人类; 类D--工人学生类。 例3. 类A--家具类; 类B--沙发类; 类C--床类; 类D--沙发床类。 29 百度搜索“70edu”或“70教育网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,70教育网,提供经典教育范文C++教程继承与派生(5)在线全文阅读。
相关推荐: