C++学习笔记(8)——继承中的二义性问题和虚基类

晨曦之光 发布于 2012/03/09 14:16
阅读 1K+
收藏 0
本博客( http://blog.csdn.net/livelylittlefish )贴出作者(三二一、小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正!
    
     
1定义基类CBase,并定义CBase的派生类CDerived1CDerived2,在定义CDerived1CDerived2的派生类CDerived12,观察二义性。 
   
   
代码如下:
/************************************************************************
* 二义性问题
***********************************************************************
*/

// 基类
class  CBase
{
    
int a;
public:
    
int x;
    
void func();
}
;

// 派生类1
class  CDerive1: public  CBase
{
    
int b;
public:
    
int y;
    
void func1();
}
;

// 派生类2
class  CDerive2: public  CBase
{
    
int c;
public:
    
int z;
    
void func2();
}
;

// 子派生类
class  CDerive12:CDerive1,CDerive2
{
    
int d;
public:
    
int yz;
    
int func12()
    
{
        x
=10;    //error C2385: 'CDerived12::x' is ambiguous
        func();    //error C2385: 'CDerived12::func' is ambiguous
    }

}
;

void  main()
{
    CDerived12 obj;
}
    
    
说明:
对于x=10;语句提示的警告如下:
warning C4385: could be the 'x' in base 'CBase' of base 'CDerive1' of class 'CDerive12' or the 'x' in base 'CBase' of base 'CDerive2' of class 'CDerive12'
 
对于func();语句提示的警告如下:
warning C4385: could be the 'func' in base 'CBase' of base 'CDerive1' of class 'CDerive12' or the 'func' in base 'CBase' of base 'CDerive2' of class 'CDerive12'
 
解析:
当一个基类被一个派生类间接继承多次时,或者说在多条继承链路有公共的基类,那么该基类就会存在多个备份,系统无法分辨对基类成员的引用是通过哪个派生类继承来的。于是编译器对于这种不确定性问题发出错误信息。
上图的例子,4个类的继承关系如下:
  
   
    
   
所以,在函数func12中访问x或者func函数时,编译器就不知道是CDerive1CBase继承来的,还是CDerive2CBase继承来的。  
要注意二义性(ambiguity)检查是在访问控制或类型检查之前进行的,因此当不同基类成员中具有相同名字时就会出现二义性,即使只有一个名字可以被派生类访问或只有一个名字的类型与要求相符。
 
解决二义性问题的方法:
1.利用范围运算符指明所要调用的成员的类属范围;
2.在派生类中重新定义一个与基类中同名的成员,使该成员隐蔽基类的同名成员;
3.将公共基类说明为虚基类,避免在派生类中保留多个基类的备份,而只保存一个实例
 
虚基类:
虚基类的定义:在定义派生类时,要在基类描述前加关键字virtual。这称为虚基类机制
 
引入虚基类的原因:
防止二义性;
使派生类中只有公共基类的一个数据副本;

原文链接:http://blog.csdn.net/livelylittlefish/article/details/2171236
加载中
返回顶部
顶部