10.3.2 二义性问题
一般来说,在派生类中对基类成员的访问应当具有唯一性,但在多基继承时,如果多个基类中存在同名成员的情况,造成编译器无法判断具体要访问的是哪个基类中的成员,则称为对基类成员访问的二义性问题,如代码10.2所示。
代码10.2 对基类成员访问的二义性MultiBaseProblem
<———————————-文件名:example1002.cpp———————————————> 01 #include<iostream> 02 using namespace std; 03 class A//类A的定义 04 { 05 public: 06 void print()//类A中定义了print函数 07 { 08 cout<<"Hello,this is A"<<endl; 09 } 10 }; 11 class B//类B的定义 12 { 13 public: 14 void print()//类B中同样定义了print函数 15 { 16 cout<<"Hello,this is B"<<endl; 17 } 18 }; 19 class C:public A,public B//类C由类A和类B共同派生而来 20 { 21 public: 22 void disp() 23 { 24 print();//编译器无法决定采用类A中定义的版本还是类B中的版本 25 } 26 }; 27 int main() 28 { 29 C exC; 30 exC. disp();//派生类内访问对象成员的二义性 31 exC. print();//外部通过派生类对象访问基类成员的二义性 32 return 0; 33 }编译运行,编译器给出如下错误信息。 error C2385:'C:print'is ambiguous
【代码解析】代码第19行的类C是由类A和类B派生而来的,且派生方式都为public,这样,在类C中访问print函数或外部通过C的对象访问print函数时,编译器无法判断到底应调用类A中的print函数还是类B中的print函数,出现二义性错误。
在多基派生时,为了能清楚地表示出各个类之间的关系,明确派生类中可见成员的归属,常采用一种无回路有向图(Directed Acyclic Graph)表示法,代码10.2可直观地体现为图10.3所示。
从图10.3可以看出,类A和类B是类C的两个基类,且类A中的print函数和类B中的print函数在类C中均可见,因此,简单地在派生类C中调用print函数会出现二义性错误。
图 10.3 DAG图表示法
注意
即使多个基类中存在某个同名成员,只要有一个基类的成员在派生类中是可见的,就不会出现二义性问题。