大胖的部落格

Just a note

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  112 随笔 :: 0 文章 :: 3 评论 :: 0 Trackbacks
虚拟继承时:
1、当虚基类的成员通过不同派生路径继承,并没有被改写时,派生类对该虚基类成员的调用,不存在二义性。
2、如果一个是虚基类成员,另一个是虚基类派生类成员,也不存在二义性。(改写后的派生类成员优先级高于共享虚基类成员)
3、如果两个成员都来自后续派生类,那么存在二义性。

如下fun1,fun2,fun3分别代表以上三种情况
class A
{
public:
    A()
{}
    
void fun1(){cout<<"A1"<<endl;}
    
void fun2(){cout<<"A2"<<endl;}
    
void fun3(){cout<<"A3"<<endl;}
}
;

//virtual inheritance
class B: virtual public A
{
public:
    B()
{}
    
void fun3(){cout<<"B3"<<endl;}
    
void fun2(){cout<<"B2"<<endl;}
}
;

//virtual inheritance
class C :virtual public A
{
public:
    C()
{}
    
void fun3(){cout<<"C3"<<endl;}
}
;

class D : public C, public B
{
public:
    D()
{}
}
;

int main()
{
    D d;
    d.fun1();    
//ok, call A::fun1()
    d.fun2();    //ok, call B::fun2()
    d.fun3();    //error, ambiguous, could be B::fun(), or C::fun()
    d.C::fun3(); //ok
    return 0;
}


非虚拟继承时,以上三种情况均存在二义性,因为每个继承得到的实例优先级是一样的。
class A
{
public:
    A()
{}
    
void fun1(){cout<<"A1"<<endl;}
    
void fun2(){cout<<"A2"<<endl;}
    
void fun3(){cout<<"A3"<<endl;}
}
;

class B: public A
{
public:
    B()
{}
    
void fun3(){cout<<"B3"<<endl;}
    
void fun2(){cout<<"B2"<<endl;}
}
;

class C: public A
{
public:
    C()
{}
    
void fun3(){cout<<"C3"<<endl;}
}
;

class D : public C, public B
{
public:
    D()
{}
}
;


int main()
{
    D d;
    d.fun1();    
//error, ambiguous
    d.fun2();    //error, ambiguous
    d.fun3();    //error, ambiguous
    d.C::fun3(); //ok
    return 0;
}

可以通过使用类域操作符来限定访问,消除二义性。



当编译器解析一个类成员时,按如下顺序:
1、局部域
2、类域
3、基类域
若哪一步解析成功,不会继续解析后面的,所以即使前面步骤里解析出来的成员无法访问,也不会继续解析后面步骤里可以访问的成员。

如下例子中,C里的fun2被解析成为父类中的private成员,尽管全局的fun2可以访问。
class A
{
private:
    
void fun2(){cout<<"A2"<<endl;}
}
;

void fun2(){}

class C: public A
{
    
void test()
    
{
        fun2();        
//error, A::fun2 is private
        ::fun2();    //ok
    }

}
;


如下例子中,虽然A::fun2()是private,无法访问,B::fun2()是public,可以访问,但仍然是二义性。
class A
{
private:
    
void fun2(){cout<<"A2"<<endl;}
}
;

class B
{
public:
    
void fun2(){cout<<"B2"<<endl;}
}
;

class C: public A, public B
{
}
;


int main()
{
    C c;
    c.fun2();    
//error
    return 0;
}
posted on 2009-06-02 09:49 大胖 阅读(249) 评论(0)  编辑 收藏 引用 所属分类: C++

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