3

类 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。这也不利于方便。

4

1 回答 1

3

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

这很好地显示了代码的作用,并且可以解决您的问题:

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

};

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

于 2013-05-23T08:58:11.737 回答