<C++学习笔记一>——多继承

来源:互联网 发布:windows to go u盘推荐 编辑:程序博客网 时间:2024/06/05 19:31

本篇文章来自转载哦,感觉不错!

一般说来,在派生类中对基类成员的访问应该是唯一的,但是,由于多继承情况下,可能造成对基类中某成员的访问出现了不唯一的情况,则称为对基类成员访问的二义性问题。
 
实际上,在上例已经出现过这一问题,回忆一下上例中,派生类A的两基类B1和B2中都有一个成员函数print()。如果在派生类中访问print()函数,到底是哪一个基类的呢?于是出现了二义性。但是在上例中解决了这个问题,其办法是通过作用域运算符::进行了限定。如果不加以限定,则会出现二义性问题。

下面再举一个简单的例子,对二义性问题进行深入讨论。例如:

class A{public:void f();};class B{public:void f();void g();};class C : public A, public B{public:void g();void h();};

如果定义一个类C的对象c1:C c1;
则对函数f()的访问 c1.f();
便具有二义性:是访问类A中的f(),还是访问类B中的f()呢?
解决的方法可用前面用过的成员名限定法来消除二义性,例如:c1.A::f();
或者 c1.B::f();

但是,最好的解决办法是在类C中定义一个同名成员f(),类C中的f()再根据需要来决定调用A::f(),还是B::f(),还是两者皆有,这样,c1.f()将调用C::f()。

同样地,类C中成员函数调用f()也会出现二义性问题。例如:viod C::h()
这里有二义性问题,该函数应修改为:void C::h()
或者 void C::h()
或者 void C::f()
另外,在前例中,类B中有一个成员函数g(),类C中也有一个成员函数g()。这时, c1.g();不存在二义性,它是指C::g(),而不是指B::g()。因为这两个g()函数,一个出现在基类B,一个出现在派生类C,规定派生类的成员将支配基类中的同名成员。因此,上例中类C中的g()支配类B中的g(),不存在二义性,可选择支配者的那个名字。

当一个派生类从多个基类派生类,而这些基类又有一个共同的基类,则对该基类中说明的成员进行访问时,也可能会出现二义性。例如:

class A{public:int a;};class B1 : public A{private:int b1;};class B2 : public A{private:int b2;};class C : public B1, public B2{public:int f();private:int c;};

已知:C c1;

  下面的两个访问都有二义性:

  c1.a;
  c1.A::a;

  而下面的两个访问是正确的:

  c1.B1::a;
  c1.B2::a;

  类C的成员函数f()用如下定义可以消除二义性:

  int C::f()
   {
    retrun B1::a + B2::a;
   }

  由于二义性的原因,一个类不可以从同一个类中直接继承一次以上,例如:

  class A : public B, public B
 
  这是错误的。

本文来源:http://developer.zdnet.com.cn/2007/1030/591018.shtml

1 0
原创粉丝点击