0

Here is my example code:

class Interface {
    public:
        virtual void foo(const Interface &interface) = 0;
};

class A : public Interface {
    public:
        void foo(const A &a) {
                // do something with another object of same type
        }
};

class B : public Interface {
    public:
        void foo(const B &b) {
        }
};

There is a warning:

warning: 'A::foo' hides overloaded virtual function
      [-Woverloaded-virtual]
            void foo(const A &a) {
                 ^
note: hidden overloaded virtual function 'Interface::foo'
      declared here: type mismatch at 1st parameter ('const Interface &' vs
      'const A &')
            virtual void foo(const Interface &interface) = 0;

How to deal with the problem? Is adding using Interface::foo; in derived class the best solution? I think it's a common problem. Thanks a lot!

Justme0
  • 125
  • 1
  • 12
  • What does the warning say? – user253751 Jul 31 '15 at 02:25
  • 1
    I'm guessing you wanted to *override* the virtual function, not overload it. The declarations must be identical i.e. `void foo(const Interface&)`. Add `override` if you want to make it crystal clear to the compiler that you are overriding, that way it'll throw an error if you do something silly like this. – user657267 Jul 31 '15 at 02:27
  • 1
    What do you want to happen if someone does `A a; B b; a->foo(b);`? Because currently your interface says that must be implemented, but it is not. It's really not clear what the problem is, to be honest. – David Schwartz Jul 31 '15 at 08:08

4 Answers4

0

void foo(const A &a) does not override void foo(const Interface &interface). While the language allows covariant return types, you can't have covariant parameters as far as I know.

So your void foo(const A &a) is hiding (or at most overloading) the base version of the function.

If you use C++11's override keyword, the compiler should more clearly tell you that you aren't overriding. Or if you try to instantiate an A then it should fail with an error about A being abstract because it hasn't actually overridden foo.

The solution of course is to make the derived versions use the exact same parameter types for foo.

TheUndeadFish
  • 8,058
  • 1
  • 23
  • 17
0

The virtual part of your virtual void foo() function indicates that it can be overridden in a class that inherits Interface. In class A and B, you have used the same function but changed the parameters, which means that the function will be overloaded.

If you want to just override the function in the sub classes, use void foo(const Interface &interface).

For more details on overloading virtual functions see this post: Overloading a virtual function in a child class

Community
  • 1
  • 1
kingcolumbo
  • 51
  • 1
  • 5
0

Thanks @GargAnkit in comment,Here is my total solotion:

#include <iostream>
#include <string>

using std::cout;
using std::endl;

class Interface {
    public:
        int compare(const Interface &that) const {
            if (this->to_string() < that.to_string()) {
                return -1;
            } else if (this->to_string() == that.to_string()) {
                return 0;
            } else {
                return 1;
            }
        }

        virtual std::string to_string() const = 0;
};

class A : public Interface {
    public:
        std::string to_string() const override {
            return "A";
        }
};

class B : public Interface {
    public:
        std::string to_string() const override {
            return "B";
        }
};

int main() {
    A a;
    B b;
    cout << a.compare(b) << endl;
    cout << "ok" << endl;

    return 0;
}
Justme0
  • 125
  • 1
  • 12
0

For a function to be picked as an override of a function in the base class, both function must match exactly - same name, same parameters, same const/volatile qualification. If the function only differ by the qualification, they will be seen as totally non correlated functions, and the base function will not consider as overriden.

example:: **

class A
{
public:
virtual void fun(..)const{}
};
class B:public A
{
public:
void fun(..){} //violation
};

**

Ramanand Yadav
  • 309
  • 3
  • 3