C++成员函数虚覆盖和同时重载

2022-01-24 00:00:00 inheritance polymorphism c++ virtual

如果我有这样的代码:

struct A {
  virtual void f(int) {}
  virtual void f(void*) {}
};

struct B : public A {
  void f(int) {}
};

struct C : public B {
  void f(void*) {}
};


int main() {
  C c;
  c.f(1);

  return 0;
}

我收到一条错误消息,提示我正在尝试进行从 int 到 void* 的无效转换.为什么编译器不能确定他必须调用 B::f,因为这两个函数都被声明为虚拟函数?

I get an error that says that I am trying to do an invalid conversion from int to void*. Why can't compiler figure out that he has to call B::f, since both functions are declared as virtual?

在阅读了 jalf 的回答后,我进一步减少了它.这个也不行.不是很直观.

After reading jalf's answer I went and reduced it even further. This one does not work as well. Not very intuitive.

struct A {
  virtual void f(int) {}
};

struct B : public A {
  void f(void*) {}
};


int main() {
  B b;
  b.f(1);

  return 0;
}

推荐答案

简短的回答是因为这就是 C++ 中重载解析的工作方式".

The short answer is "because that's how overload resolution works in C++".

编译器在 C 类中搜索函数 F,如果找到,它会停止搜索,并尝试从中挑选一个候选函数.如果在派生类中没有找到匹配的函数,它只会在基类内部查找.

The compiler searches for functions F inside the C class, and if it finds any, it stops the search, and tries to pick a candidate among those. It only looks inside base classes if no matching functions were found in the derived class.

但是,您可以将基类函数显式引入派生类的命名空间:

However, you can explicitly introduce the base class functions into the derived class' namespace:

struct C : public B {
  void f(void*) {}
  using B::f; // Add B's f function to C's namespace, allowing it to participate in overload resolution
};

相关文章