c++成员函数虚拟覆盖和重载同时进行

时间:2022-11-25 16:54:51

If I have a code like this:

如果我有这样的代码:

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

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?

我得到一个错误,说我正在尝试做一个无效的从int到void*的转换。为什么编译器不能算出他必须调用B::f,因为两个函数都声明为虚函数?


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

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

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

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


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

  return 0;
}

3 个解决方案

#1


44  

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

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

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.

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

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

#2


-1  

Or you could do this:

或者你可以这样做:

void main()
{
    A *a = new C();
    a->f(1);  //This will call f(int) from B(Polymorphism)
}

#3


-6  

Well I think first of all you did not understand what virtual mechanism or polymorhism. When the polymorphism is achieved only by using object pointers. I think you are new to c++. Without using object pointers then there is no meaning of polymorphism or virtual keyword use base class pointer and assign the desired derived class objects to it. Then call and try it.

首先,我认为你们不了解什么是虚拟机制或多态性。当多态性仅通过使用对象指针实现时。我认为你是c++新手。如果不使用对象指针,那么就没有多态性或虚关键字的含义,使用基类指针并为其分配所需的派生类对象。然后打电话试试。

#1


44  

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

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

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.

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

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

#2


-1  

Or you could do this:

或者你可以这样做:

void main()
{
    A *a = new C();
    a->f(1);  //This will call f(int) from B(Polymorphism)
}

#3


-6  

Well I think first of all you did not understand what virtual mechanism or polymorhism. When the polymorphism is achieved only by using object pointers. I think you are new to c++. Without using object pointers then there is no meaning of polymorphism or virtual keyword use base class pointer and assign the desired derived class objects to it. Then call and try it.

首先,我认为你们不了解什么是虚拟机制或多态性。当多态性仅通过使用对象指针实现时。我认为你是c++新手。如果不使用对象指针,那么就没有多态性或虚关键字的含义,使用基类指针并为其分配所需的派生类对象。然后打电话试试。