如何处理基类函数已经重载不同访问权限时的名称隐藏问题

How to deal with name hiding when base class function already overloaded with different access

本文关键字:权限 访问权 访问 问题 隐藏 重载 处理 何处理 基类 类函数      更新时间:2023-10-16

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

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

在使用非虚接口习惯用法时,以不同的方式命名这两个函数(公共非虚函数和私有虚函数)会更安全、更明确。

这很好地显示了代码的功能,并将解决您的问题:

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

当然,不要忘记改变层次结构