随笔-59  评论-36  文章-0  trackbacks-0
问题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中的名称的。
posted on 2009-10-28 12:51 zhaoyg 阅读(1118) 评论(0)  编辑 收藏 引用 所属分类: C/C++学习笔记

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理