钻石型继承中的虚函数问题

钻石型继承中的虚函数问题
问题1:
class  Base1
{
public:
    
virtual void f()
    
{
        cout 
<< "Base1::f" << endl;
    }

    
virtual void g()
    
{
        cout 
<< "Base1::g" << endl;
    }

}
;
class  Base2 : public   virtual  Base1
{
public:

    
virtual void f()
    
{
        cout 
<< "Base2::f" << endl;
    }

    
virtual void g()
    
{
        cout 
<< "Base2::g" << endl;
    }

}
;

class  Base3: public   virtual  Base1
{
public:

    
virtual void f()
    
{
        cout 
<< "Base3::f" << endl;
    }

    
virtual void g()
    
{
        cout 
<< "Base3::g" << endl;
    }

}
;

class  Derive :  public  Base2,  public  Base3  {
public:
virtual void g() { cout << "Derive::g1" << endl; }
}
;

以上代码是在论坛中遇见的,当时我并没有立刻反应上来这是什么缘故,思索一阵后,才弄明白。
原来,在Derive中没有重写f函数,又因为当派生类没有重写基类的虚函数时,派生类对象对该虚函数的调用,将会调用其基类中的版本,而Derive又是多继承,于是在Derive继承时就不知道Base1中的虚函数表应该记录哪个版本的f函数,是Base2,还是Base3。
因为Derive中已重定义g函数,Base1的虚函数表记录的是Derive::g。

==============================================================================

问题2:
代码来源<effective C++>2nd

class  Lottery
{
public :
  
virtual   int  draw();
};

class  GraphicalObject 
{
public :
  
virtual   int  draw();
};

class  LotterySimulation:  public  Lottery,
                         
public  GraphicalObject 
{
  
//  没有声明draw
};

LotterySimulation 
* pls  =   new  LotterySimulation;

pls
-> draw();    //  错误! ---- 二义

因为LotterySimulation中存在两个名为draw的函数,于是调用存在二义性。同时,即便更改其中一个draw的访问性也不能避免这种二义性,因为改变一个类成员的访问权限不应该改变程序的含义。
对于如下代码,仍然存在二义性
class  SpecialLotterySimulation:  public  LotterySimulation 
{
public :
  
virtual   int  draw();
};

pls 
=   new  SpecialLotterySimulation;

pls
-> draw();      //  错误!  还是有二义
因为,pls的静态类型是LotterySimulation,而名字的查找是向上进行的,所以即便SpecialLotterySimulation中定义了一个draw,对pls来说他是不会查看SpecialLotterySimilation中的名称的。

你可能感兴趣的:(钻石型继承中的虚函数问题)