多继承引起的二义性
Posted T丶jl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多继承引起的二义性相关的知识,希望对你有一定的参考价值。
多重继承可以反映现实生活中的实际情况,能有有效的处理一些较复杂的问题,使编程具有灵活性。但是多重继承也引起了一些值得注意的问题,它增加了程序的复杂度,使程序的编写和维护变得相当困难。其中最常见的问题就是继承成员同名而产生的二义性(Ambiguous)问题。
①调用不同基类的同名成员时可能出现二义性
1 class A 2 { 3 public: 4 void setA(int a); 5 int get(); 6 private: 7 int a; 8 } ; 9 class B 10 { 11 public: 12 void setB(int b); 13 int get(); 14 private: 15 int b; 16 } ; 17 18 class C:public A,public B 19 { 20 public: 21 void setC(int c); 22 int getC(); 23 private: 24 int c; 25 };
在执行obj.get();时将是有二义性的。因为类C分别从类A类B继承了两个不同版本的get()成员函数,因此,obj.get();到底调用哪个get()版本,编译器将无从知晓。
对于这种二义性问题,常见有两种解决方法:
(1)使用作用域分辨符::加以消除。
obj.A::get();
obj.B::get();
(2)在类C中也定义成员函数get()函数,则有类C的对象obj访问get()函数obj.get()没有二义性,这是因为当派生类中的成员与基类中的成员重名时,派生类中的同名成员将被调用。
1 class A 2 { 3 public: 4 void setA(int a); 5 int get(); 6 private: 7 int a; 8 } ; 9 class B 10 { 11 public: 12 void setB(int b); 13 int get(); 14 private: 15 int b; 16 } ; 17 18 class C:public A,public B 19 { 20 public: 21 void setC(int c); 22 int get(); 23 //此处改为这样 24 private: 25 int c; 26 };
②访问共同基类的成员时可能出现二义性
当一个派生类有多个基类,而这些基类又有一个共同的基类时,也就是所谓的菱形继承。这时对这个共同基类中成员的访问可能出现二义性。
1 class A 2 { 3 public: 4 void disp(); 5 private: 6 int a; 7 }; 8 9 class B1:public A 10 { 11 public: 12 void dispB1(); 13 private: 14 int b1; 15 }; 16 class B2:public A 17 { 18 public: 19 void dispB2(); 20 private: 21 int b2; 22 }; 23 24 class C:public B1,public B2 25 { 26 public: 27 void dispC(); 28 private: 29 int c; 30 };
在此类结构下,如果创建类C的对象c1:
C c1;
则下面的两个访问都有二义性:
c1.disp();
c1.A::disp();
这是因为B1,B2分别从类A中继承了一个disp()成员函数的副本,因此类C中就有了分别从类B1,B2两条不同路线上继承过来的disp()版本,尽管这两个版本的函数完全相同,但是语句“c1.disp();”将使编译器无从知晓到底调用从类B1继承来的disp(),还是调用从类B2继承来的disp(),这就是导致二义性的原因。
语句“c1.A::disp();”产生二义性的道理相同,不过下面的两条调用语句却是正确的:
c1.B1::disp();
c1.B2::disp();
因为通过“B1::”及“B2::”的限定,明确告诉编译器应该调用从哪条路径上继承过来的disp()。
在一个类中保留间接共同基类 的多份同名成员,虽然有时是必要的,可以在不同的数据成员中分别存放不同的数据,也可以通过构造函数分别对它们进行初始化。但在大多数情况下,这种现象是人们不希望出现的。
因为保留多份数据成员的副本,不仅占用较多的存储空间,还增加了访问这些成员时的困难。而且在实际上,并不需要有多份副本,为此,c++中提供了虚基类(Virtual Base Class)技术来解决这个问题。
关于虚基类方面的内容请跳转至http://www.cnblogs.com/tenjl-exv/p/7625836.html
以上是关于多继承引起的二义性的主要内容,如果未能解决你的问题,请参考以下文章