为什么我需要重新声明重载的虚函数?

我有一个带有两个重载函数的基类f(void)f(int). 类Derived工具f(int)调用f(void)。只Derived2执行f(void)

编译器拒绝实现,Derived::f(int)因为它想调用,f(int)但我没有提供参数,因为我想调用f(void). 为什么编译器拒绝它?为什么添加行可以virtual int f(void) = 0;解决我的问题?

class Base
{
public:
  explicit Base(void) {}
  virtual ~Base(void) {}

  virtual int f(void) = 0;
  virtual int f(int i) = 0;
};

class Derived : public Base
{
public:
  // provide implementation for f(int) which uses f(void). Does not compile.
  virtual int f(int i) {puts("Derived::f(int)"); return f();}
  // code only compiles by adding the following line.
  virtual int f(void) = 0;
};

class Derived2 : public Derived
{
public:
  // overwrite only f(void). f(int) is implemented by Derived.
  virtual int f(void) {puts("Derived2::f(void)"); return 4;}
};

int main(void)
{
  Base * p = new Derived2();
  int i0 = p->f();  // outputs Derived2::f(void) and returns 4
  int i1 = p->f(1); // outputs "Derived::f(int) Derived2::f(void)" and return 4
  delete p;
  return 0;
}

回答

Derived::f隐藏Base::f. 鉴于return f();在体内Derived::f(int),这个名字f是在范围中Derived,则名称查找停止。中的名称Base将不会被找到并参与重载解析。

名称查找按如下所述检查作用域,直到找到至少一个任何类型的声明,此时查找停止并且不再检查其他作用域。

您可以添加using Base::f;将名称从Base引入范围内Derived

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

  // provide implementation for f(int) which uses f(void).
  virtual int f(int i) {puts("Derived::f(int)"); return f();}
};


以上是为什么我需要重新声明重载的虚函数?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>