Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ member function virtual override and overload at the same time

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?


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; } 
like image 666
bombardier Avatar asked Feb 25 '09 13:02

bombardier


People also ask

Can a function be virtual and override?

Because virtual functions are called only for objects of class types, you cannot declare global or static functions as virtual . The virtual keyword can be used when declaring overriding functions in a derived class, but it is unnecessary; overrides of virtual functions are always virtual.

Can a virtual function be overloaded?

It is not possible for these functions to get overloaded.

Do you have to override a virtual function?

It is not mandatory for the derived class to override (or re-define the virtual function), in that case, the base class version of the function is used. A class may have virtual destructor but it cannot have a virtual constructor.

Is it possible to avoid a virtual method from getting overridden in C++?

In C++, there's no way to forbid it, it's just that by definition of "override", only virtual functions can be "overridden".


1 Answers

The short answer is "because that's how overload resolution works in 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.

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 }; 
like image 189
jalf Avatar answered Oct 02 '22 18:10

jalf