当基类函数已经过载不同的访问时,如何处理名称隐藏

时间:2013-05-23 08:01:51

标签: c++ oop inheritance polymorphism overloading

类foo充当接口,它具有纯虚函数,并且为了方便也提供了一些具有相同名称的公共重载函数,因此派生类不需要在每个实现中提供它们。

但由于派生类必须覆盖纯虚函数,因此它隐藏了foo的公共函数 我尝试使用"使用foo :: A"但它不会工作因为"使用"将带来所有功能,包括私有功能,并导致编译器错误"错误C2876:' foo' :并非所有重载都可以访问"。

class foo
{
private:
    virtual void A(int a)=0;
public:
    void A()
    {
        A(1000);
    }
    void A(int a, int b)
    {
        A(a+b);
    }

};

class bar : public foo
{
private:
    virtual void A(int a)
    {
        cout << a << "\n";
    }

};

int main()
{
    bar x;
    x.A();
    return 0;
}

我知道我可以重新定义从foo派生的每个类中的每个重载函数,但这会破坏方便的目的。
或者我可以在调用A()之前将bar转换为foo,但是这种方法会变得混乱,因为我需要记住哪个函数在哪个类中定义。例如:

class foo
{
private:
    virtual void A(int a)=0;
public:
    void A()
    {
        A(1000);
    }
    void A(int a, int b)
    {
        A(a+b);
    }
};

class bar : public foo
{
private:
    virtual void A(int a)
    {
        cout << "bar:" << a << "\n";
    }
public:
    void A(int a, int b, int c)
    {
        A(a+b+c);
    }
};

class foobar : public bar
{
private:
    virtual void A(int a)
    {
        cout << "foobar:" << a << "\n";
    }
};

int main()
{
    foobar x;
    x.foo::A();
    x.bar::A(1,2,3);
    return 0;
}

我需要清楚地记得来自foo的一个没有参数,而有三个参数的A来自bar。这也不方便。

1 个答案:

答案 0 :(得分:2)

使用非虚拟接口惯用法时,您应该以不同的方式命名这两个功能(公共非虚拟和私有虚拟)。

这很好地展示了代码的作用,并将解决您的问题:

class foo
{
private:
    virtual void doA(int a)=0;
public:
    void A()
    {
        doA(1000);
    }
    void A(int a, int b)
    {
        doA(a+b);
    }

};

当然不要忘记更改层次结构。