2

我有一个关于方法重载和继承的问题。我有以下程序:

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

可悲的是,g++ 告诉我“没有匹配的函数可以调用 'QuadFunc::value(Point&)'”。就我而言,如果我调用 QuadFunc::value(Point&),则调用应该重定向到父类 Func。如果我将 value(Point &p) 重命名为 p_value(Point &p) 并改为调用该方法,这确实有效。我能以某种方式让重载的方法按预期工作吗?

4

3 回答 3

5

您的覆盖QuadFunc 隐藏Func.

Func您可以通过使用对对象的引用(或指针)来绕过这种隐藏QuadFunc

QuadFunc qf;
Func &func = qf;

Face f;
Point p;

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

value更好的解决方案是将符号QuadFunc从类中“导入”到Func类中。您可以使用以下using关键字:

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

    // ...
};

然后,您不必使用参考解决方法。

于 2013-07-12T08:36:00.190 回答
2

using如果要从基类重载成员函数(也可能需要已经提到的),则需要使用该指令virtual,因此代码将变为:

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

  using Func::value; //this is what you need
  Real value(Face &f) override {return 0.;}
};
于 2013-07-12T08:38:26.307 回答
0

如果您对编译器是显式的,则虚函数将隐藏函数值(Point&),如下所示:

  func.Func::value(p);

它确实有效!在这里测试一下。

或者,您可以添加

using Func::value;

正如另一个答案所建议的那样,进入 QuadFunc 声明。

于 2013-07-12T08:37:59.250 回答