XerXes
XerXes

Reputation: 733

Access overloaded base class method with same name as derived method

I'm attempting to call a method from a base class with the same name as a method in the derived class. Here's a simplified example:

#include <iostream>

using namespace std;

class Base
{
public:
    void print() {
        cout << "Printing from base" << endl;
    }

    void print(int num) {
        cout << "Printing number from base: " << num << endl;
    }
};

class Derived : public Base
{
    using Base::print;

public:
    void print() {
        cout << "Printing from derived" << endl;
    }
};


int main()
{
    Derived x;

    x.print();
    x.Base::print(1);

    //x.print(1); // Gives a compilation error

    return 0;
}

Basically, I'd like to be able to call x.print(1) and get "Printing number from base: 1", that is, automatically call the method which matches the signature, even though it resides in the base class.

Without the using Base::print;, I get error: no matching function for call to 'Derived::print(int)', which makes perfect sense due to name hiding.

Thus, I added that line, but now the error is error: 'void Base::print(int)' is inaccessible

Why is this the case? I use public inheritance, so I would have thought it was readily available?

As demonstrated in the example, it works fine to manually call x.Base::print(1);, but I would like to do it more transparently. Then of course I can re-implement a wrapper to the function in the derived class, but that does not seem very elegant either.

I apologize if this has been covered in an earlier question, I read a bunch of them and found a lot of similar cases, but nothing that helped me.

Upvotes: 0

Views: 4015

Answers (2)

Aesthete
Aesthete

Reputation: 18850

You can make your functions virtual. Any virtual functions inherited from the base class that aren't overloaded will be called through the derived class.

class base 
{
  public:
    virtual void Foo() {}
}

class Derived
{
}

Derived d;
d.foo(); // calls base::foo()

Upvotes: 0

The placement of the using directive decides about the visibility. Simply place it into the public area and you should be fine:

//...
class Derived : public Base
{

public:
    using Base::print;

    void print() {
        cout << "Printing from base" << endl;
    }
};
//...

http://ideone.com/06NNk

Upvotes: 4

Related Questions