#include
class base
{
public:
virtual void print (int a)
{
std::cout << \"a: \" << a << \" base\\n\";
}
derived::print
does not override any member function in base
. It is declared as having a single parameter of type double
but the two virtual member functions named print
in base
are declared as having one and two parameters of type int
.
When you use b->print(d)
, only member functions in base
are considered during overload resolution, so only void base::print(int)
and void base::print(int, int)
are considered. void derived::print(double)
can't be found because the compiler has no idea that b
points to a 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 runtime.
(On a somewhat related note, derived::print
hides the two base::print
member functions, so if you were to try to use one of the base class print
functions, e.g., derived().print(1, 1)
, it would fail. You would need to use a using declaration to make those member functions available during name lookup.)
Overload resolution happens at compile time. Overrides happen at run time.
Therefore, the overload resolution of b->print(d);
happens first. This selects Base::print(int)
because it's the only one-argument print
.
At runtime, b
points to a Derived
object that has no override for Base::print(int)
. Therefore, Base::print(int)
is still called.
Because double can be automatically converted to an int in the first definition it sees (in the base class)
See explicit
keyword or this question