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

By : czz
Source: Stackoverflow.com
Question!

Class foo act as interface, it has a pure virtual function and also provide some public overloaded function with same name for convenience so that derived class won't need to provide them in every implementation.

But since derived class must override the pure virtual function, it hides foo's public function.
I tried with "using foo::A", but it won't work because "using" will bring all function including the private one and result in compiler error "error C2876: 'foo' : not all overloads are accessible".

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

I know I can redefine every overloaded function in every class which derived from foo, but this defeat the purpose of convenience.
Or I can cast bar to foo before calling A(), but this approach will get confused since I need to remember which function is define in which class. For example:

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

I need to clearly remember A withouth argument come from foo, and A with three arguments come from bar. This is also not good for convenience.

By : czz


Answers
When using the non virtual interface idiom, you should name the two functions (the public non-virtual and the private virtual) differently.

This shows well what the code do, and would solve your problem:

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

};

And of course don't forget to change in the hierarchy.

By : JBL


This video can help you solving your question :)
By: admin