What are the rules for finding virtual functions?

#include <iostream> class base { public: virtual void print (int a) { std::cout << "a: " << a << " base\n"; } virtual void print (int a, int b) { std::cout << "base\n"; } }; class derived : public base { public: virtual void print (double d) { std::cout << "derived\n"; } }; int main () { int i = 10; double d = 10000.0; base *b = new derived (); b->print (i, i); b->print (d); return 0; } 

The output of this function:

 base a: 10000 base 
  • Why don't b->print (d) refer to the implementation of the derived class and do a static conversion to 'd' to ensure that the implementation matches the base class?
  • Which rule applies here when looking for a virtual function?
+4
source share
3 answers

derived::print does not override any member function in base . It is declared as having a single parameter of type double , but two virtual member functions named print in base declared as having one and two parameters of type int .

When you use b->print(d) , only the member functions in base are taken into account during overload resolution, so only void base::print(int) and void base::print(int, int) are taken into account. void derived::print(double) cannot be found because the compiler does not know that b points to the derived object.

If derived were to override one of the two print functions declared as virtual member functions in base , then that override would be called at run time.

(In some respects, the note derived::print hides two member functions of base::print , so if you try to use one of the functions of the print base class, for example, derived().print(1, 1) , it will fail. You will need to use a service declaration to make these member functions available during the name lookup.)

+8
source

Overload resolution occurs at compile time. Switching occurs at runtime.

Therefore, overload resolution is first performed b->print(d); . This selects Base::print(int) because it is the only argument to print .

At run time, b points to a Derived object that does not have an override for Base::print(int) . Therefore, Base::print(int) is still being called.

+1
source

Since double can be automatically converted to int in the first definition that it sees (in the base class)

See explicit keyword or this question

0
source

Source: https://habr.com/ru/post/1344522/


All Articles