hfhc2
hfhc2

Reputation: 4391

Calling the right overloaded parent method

I have a question regarding method overloading and inheritance. I have the following program:

class Face {};
class Point {};

typedef double Real;

class Func
{
private:
  const char *m_name, *m_desc;

public:
  Func(const char *name,
       const char *desc) : m_name(name), m_desc(desc) {}

  virtual Real value(Face &f) = 0;

  Real value(Point &p) {return 0.;}

  virtual ~Func() {}
};


class QuadFunc : public Func
{
public:
  QuadFunc() : Func("quad", "Quadratic") {}

  Real value(Face &f) override {return 0.;}
};

int main(int argc, char **argv)
{
  QuadFunc func;

  Face f;
  Point p;

  func.value(f);
  // why doesn't this work?
  func.value(p);

  return 0;
}

Sadly g++ tells me that there is "no matching function for call to ‘QuadFunc::value(Point&)’". As far as I am concerned if I call QuadFunc::value(Point&) the call should be redirected to the parent class Func. This does work if I rename value(Point &p) to p_value(Point &p) and call that method instead. Can I somehow get the overloaded method to work as I expect?

Upvotes: 2

Views: 206

Answers (3)

Stefano Falasca
Stefano Falasca

Reputation: 9097

The virtual function is hiding the function value(Point&), if you are explicit to the compiler as in:

  func.Func::value(p);

it does work! Test it here.

In alternative you can just add

using Func::value;

into the QuadFunc declaration, as suggested by another answer.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409166

Your override in QuadFunc hides the overloaded function in Func.

You can bypass this hiding, by using a Func reference (or pointer) to a QuadFunc object:

QuadFunc qf;
Func &func = qf;

Face f;
Point p;

func.value(f);
func.value(p);  // Works

A better solution is to "import" the value symbol into the QuadFunc class from the Func class. You do that with the using keyword:

class QuadFunc : public Func
{
public:
    using Func::value;

    // ...
};

Then you don't have to use the reference workaround.

Upvotes: 5

Zlatomir
Zlatomir

Reputation: 7034

You need to use the using directive if you want to overload a member function from a base class (also you might need the already mentioned virtual), so the code will become:

class QuadFunc : public Func
{
public:
  QuadFunc() : Func("quad", "Quadratic") {}

  using Func::value; //this is what you need
  Real value(Face &f) override {return 0.;}
};

Upvotes: 2

Related Questions