30

如果我有这样的代码:

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,因为这两个函数都被声明为虚拟函数?


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

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

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


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

  return 0;
}
4

3 回答 3

44

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

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

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

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
};
于 2009-02-25T13:11:06.587 回答
-1

或者你可以这样做:

void main()
{
    A *a = new C();
    a->f(1);  //This will call f(int) from B(Polymorphism)
}
于 2014-04-01T21:21:56.987 回答
-6

那么我想首先你不明白什么是虚拟机制或多态。仅通过使用对象指针来实现多态性时。我认为你是 C++ 的新手。如果不使用对象指针,则没有多态性或虚拟关键字使用基类指针并将所需的派生类对象分配给它的意义。然后打电话试试。

于 2009-10-22T06:19:54.297 回答