10.7.3 公共基类
如果多基派生时出现公共基类,并且没有对该基类使用virtual虚拟派生,在对象赋值和指针转换时,可能会出现二义性错误。举例来说,如图10.11所示的派生结构,其类定义简写为如下形式。
图 10.11 共同基类时的情况
class A class B:public A class C:public A class D:public B,public C
此时,汇聚处类D对象的成员在内存中的分布如图10.12,此时,在类D对象中会出现两份类A对象的副本。
此时,虽然下述语句是合法的,如下所示。
a=b; a=c; b=d; c=d; pA=pB; pA=pC; pB=pD; pC=pD;但在执行下述语句时,会导致二义性错误。 a=d; pA=pD;
图 10.12 共同基类多基派生对象的内存分布图
在类D对象d中有两份类A对象的副本,所以C++编译器不知道究竟应该用哪一个来对类A对象赋值,究竟用哪一个的地址来对类A指针pA赋值,会导致二义性错误。
克服这种二义性的方法如下所述。
1.对指针显式指明路径
pA=(A)(B)pD;
这样,编译器便可以明确地判断出应使用类D中类B复制中的类A副本的首地址来为pA赋值。
2.先将指针转到不会产生二义性的类型
pA=(B*)pD;//隐式转换 或 B*pTemp=pD; pA=pTemp;3.对象赋值采用强制类型转换 a=B(d);//C语言的写法也可以,即a=(B)d;当使用强制转换时,使用pA指向类D对象d中的其他成员,也要显式指明路径,如下列语句是错误的。 DppD=(D)pA;正确的写法应该是如下形式。 DppD=(D)(B*)pA;