Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload pure virtual function with non pure virtual version [duplicate]

Tags:

c++

With Base and Derived defined like this:

class Base {

    public:
        virtual int f1(int a) const = 0;
        virtual int f2(int a, int b) const { return a+b;}
};

class Derived : public Base {

    public:
        int f1(int a) const { return a; }
}; 

int main() {
    Derived obj;
    cout << obj.f1(1) << endl;
    cout << obj.f2(1, 2) << endl;
}

The result is

1
3

obj.f1(1) uses the f1 implementation from Derived and obj.f2(1, 2) uses the implementation inherited from Base, which is what I want.

Now, I would like these two functions to have the same name, f, so the base class provides an implementation when there are two parameters and the derived class must implement the single parameter version (that's why it's pure virtual).

However, if I do this (just rename f1 and f2 to f):

class Base {

    public:
        virtual int f(int a) const = 0;
        virtual int f(int a, int b) const { return a + b;}
};

class Derived : public Base {

    public:
        int f(int a) const { return a; }
};

int main() {
    Derived obj;
    cout << obj.f(1) << endl;
    cout << obj.f(1, 2) << endl;
}

I get the following error:

20:23: error: no matching function for call to 'Derived::f(int, int)'
20:23: note: candidate is:
14:13: note: virtual int Derived::f(int) const
14:13: note:   candidate expects 1 argument, 2 provided

Why is this? Is it not possible to do this kind of overloading?

like image 881
Milo Avatar asked Sep 17 '18 09:09

Milo


1 Answers

You need to write

class Derived : public Base {

    public:
        using Base::f;
        int f(int a) const { return a; }
};

Note the using statement. That brings the base class version back into scope.

like image 193
Bathsheba Avatar answered Sep 27 '22 20:09

Bathsheba