模糊访问

时间:2011-06-18 18:13:13

标签: c++ visual-c++

  

可能重复:
  Why do multiple-inherited functions with same name but different signatures not get treated as overloaded functions?

我收到错误:

ambiguous access of 'attach'
    could be the 'attach' in base 'A::A1'
    or could be the 'attach' in base 'B::B1'

这是代码:

class A
{
public:
    class A1
    {
    public:
        virtual void attach( A & a ) { }
    };
public:
};

class B
{
public:
    class B1
    {
    public:
        virtual void attach( B & b ) { }
    };
public:
};

class C : public A::A1, public B::B1
{
public:
    C(){ }
};

void main(int argc, char *argv[])
{
    A a;
    B b;
    C c;
    c.attach( a );
    c.attach( b );
}

我理解错误。编译器很困惑,它想要范围:

c.A::A1::attach( a );
c.B::B1::attach( b );

这种语法太可怕了。我可以在C中定义附加方法,而现在编译器可以获取它,但我不想定义所有这些附加方法:

class C : public A::A1, public B::B1
{
public:
    C(){ }
void attach( A & a ) { A::A1::attach(a); }
void attach( B & b ) { B::B1::attach(b); }
};

有人可以向我解释为什么编译器在明确(在我看来)应该使用哪个'attach'时会对'attach'感到困惑?任何人都可以提供不需要范围界定的解决方案吗?

更新:更新了我的第二个C示例中的范围,例如: A::A1::attach(a)

更新:在调查下面提到的副本时,我遇到了解决方案:

class C : public A::A1, public B::B1
{
public:
    using A::A1::attach;
    using B::B1::attach;
public:
    C(){ }
};

在我作为c ++程序员的18年中,我从来没有像这样使用'使用'。我甚至都不知道存在。

2 个答案:

答案 0 :(得分:3)

此功能是为了避免Fragile Base Class问题。考虑一下如果按预期工作会发生什么 - 然后A :: A1添加一个带B:B1引用的重载。突然间,所有您的呼叫网站都是模棱两可的 - 即使您没有改变任何内容。如果重载是私有的,则甚至为真。

当然,在我看来,这是毫无意义的,因为有一百万个其他方法可以打破派生类和其他问题。但这是明显的理由。

答案 1 :(得分:2)

你可以在C级写这个:

using A::A1::attach;
using B::B1::attach;

而不是

void attach( A & a ) { A::A1::attach(a); }
void attach( B & b ) { B::B1::attach(b); }