首页 > 解决方案 > 为什么我需要重新声明重载的虚函数?

问题描述

我有一个带有两个重载函数的基类f(void)f(int). 该类通过调用Derived实现。只执行。f(int)f(void)Derived2f(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;
}

标签: c++polymorphismoverloadingvirtual

解决方案


Derived::f隐藏Base::fs. 在 的主体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();}
};

推荐阅读