访问不明确

Ambiguous access

本文关键字:不明确 访问      更新时间:2023-10-16

可能重复:
为什么具有相同名称但不同签名的多个继承函数不会被视为重载函数?

我得到一个错误:

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); }
};

有人能向我解释一下,当(在我看来)应该使用哪个"附加"时,编译器为什么对"附加"感到困惑吗?有人能提供一个不需要范围界定的解决方案吗?

UPDATE:在我的第二个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年里,我从未像这样使用过"using"。我甚至不知道它的存在。

此功能是为了避免脆弱基类问题。考虑一下,如果这如您所期望的那样工作,然后A::A1添加了一个采用B::B1引用的重载,会发生什么。突然间,所有您的呼叫站点都不明确了——尽管您没有更改任何内容。如果过载是私有的,则甚至为真。

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

您可以在类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); }