单继承--多态性 多继承--二义性 ambiguous

一.单继承 –多态性

 

二.多继承- 二义性ambiguous

 

  1. 多个直接父类中  出现同名成员时产生的二义性
  2. 同一个父类  通过不同继承路径产生的二义性

 

例8-6    A1父类中的f1(),还是A2父类中的f1()

#include <iostream>

using namespace std;

class A1

{   public:

         void f1()

         {          cout<<"A1类中的函数f1()"<<endl;  }

};

class A2

{   public:

         void f1()

         {           cout<<"A2类中的函数f1()"<<endl;   } // 该成员与A1中的重名  

};

class B:public A1,public A2

{  

};

int main()

{

 B b;

 b.f1();    // 该句出错

}

 

 

#include <iostream>

using namespace std;

class A1

{   public:

         void f1()

         {          cout<<"A1类中的函数f1()"<<endl;  }

};

class A2

{   public:

         void f1()

         {           cout<<"A2类中的函数f1()"<<endl;   } // 该成员与A1中的重名  

};

class B:public A1,public A2

{  

};

int main()

{

 B b;

 b.A1::f1();    // 作用域运算符

 b.A2::f1();

}

 

#include <iostream>

using namespace std;

class A1

{   public:

         void f1()

         {          cout<<"A1类中的函数f1()"<<endl;  }

};

class A2

{   public:

         void f1()

         {           cout<<“A2类中的函数f1()”<<endl;    // 该成员与A1中的重名     }

         void f2()

         {        cout<<"A2类中的函数f2()"<<endl;       }

};

class B:public A1,public A2

{   public:

         void f2()

         {        cout<<"派生类B中的函数f2()"<<endl;        }    //  与基类A2中的成员同名

         void f3()

         {        cout<<"派生类B中的函数f3()"<<endl;      }

};

void main()

{  B b;

  b.f1();    // 该句出错

  b.f2();

  b.f3();

}

程序在编译时会出错,错误信息如下:

error C2385: 'B::f1' is ambiguous

warning C4385: could be the 'f1' in base 'A1' of class 'B'

warning C4385: or the 'f1' in base 'A2' of class 'B'

 

A1类中有一个函数成员f1(),A2类中也有一个同名的函数成员f1(),

派生类B中继承了这两个同名的成员,

类B的对象b对f1()的访问b.f1()出现了二义性,无法确定访问A1中的f1(),还是A2中的f1()?

解决方法:

使用作用域运算符“::”明确指出访问的是从哪个类中继承的成员。

例如:将b.f1()写成b.A1::f1();或b.A2::f1();

 

 

程序中,A2类和B类中还有一个同名的函数成员f2(),但b对f2的访问b.f2();在编译时并没有出错。

在类的继承层次结构中,基类和派生类具有包含关系,派生类在内层,基类外层

同名覆盖

具有包含关系的两个或多个作用域,如果在外层中声明的标识符在内层中没有同名标识符,则它在内层可见,如果内层中声明了同名标识符,则外层标识符在内层不可见,也就是内层标识符覆盖了外层的同名标识符

B类和A1类、B类和A2类都具有包含关系,对于B类和A2类,A2类在外层,B类在内层,这样,根据可见性原则,可知b.f2()访问的是B类的f2()

 

void main()

{  B b;

  b.A1::f1();

  b.A2::f1();

  b.f2();

  b.f3();

}

这时,没有出现二义性

 

多层继承中  使用作用域运算符==延伸例8-7

#include <iostream>

using namespace std;

class A

{   public:

         void fun()

         {          cout<<"A类的函数fun()"<<endl;  }

};

 

class B:public A

{   public:

         void fun()  {  cout<<"B类的函数fun()"<<endl;}

};

class C:public B

{   public:

         void fun()  {  cout<<"C类的函数fun()"<<endl;    }

};

class D:public C

{   public:

         void f()     { C::fun(); B::fun();   A::fun();         }

};

void main()

{        D d;

         d.f();

}

 

 

 

8-8如果一个派生类C 多个基类B1 B2派生,而这些基类又有一个共同的老基类A,当对该老基类A中说明的成员进行访问时,也可能出现的二义性

#include <iostream>

using namespace std;

class A

{  public:

            void fun()

           {      cout<<"A类的函数fun()"<<endl;     }

};

class B1:public A

{    };

class B2:public A

{    };

class C:public B1,public B2

{     };

void main()

{        C c;

          c.fun();

}

程序在编译时出错,错误信息如下:

error C2385: 'C::fun' is ambiguous

warning C4385: could be the 'fun' in base 'A' of base 'B1' of class 'C'

warning C4385: or the 'fun' in base 'A' of base 'B2' of class 'C'

 

图(b)中,类C继承两个基类B1和B2,而B1和B2又有一个共同的基类A,这样,类A是派生类C在两条继承路径上的公共基类,这个公共基类在派生类C的对象中将包含两个基类A的子对象,从而导致对基类成员访问时的不唯一性,

将基类A定义为虚基类,能够使得公共基类A在派生类中只产生一个子对象,就可避免二义性问题

 

法(一)作用域运算符

#include <iostream>

using namespace std;

class A

{      public:

            void fun()     {   cout<<"A类的函数fun()"<<endl;          }

};

class B1:public A { };

class B2:public A { };

class C:public B1,public B2  {  };

 main()

{        C c;

          c.B1::fun();

          c.B2::fun();

}

 

 

法(二)虚基类

#include <iostream>

using namespace std;

class A

{      public:

            void fun()    {   cout<<"A类的函数fun()"<<endl;       }

};

class B1:virtual public A { };

class B2:public virtual A { };

class C:public B1,public B2  {  };

void main()

{        C c;

          c.fun();

}

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangchuang2017

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值