Reputation: 741
I have the following objects
#include <stdio.h>
class foo_t{ };
class bar_t: public foo_t{ };
class zoo_t: public bar_t{ };
class base_t{
public:
void dostuff(foo_t * foo){ printf("Defaulting to base\n"); };
};
class derived_t: public base_t{
public:
void dostuff(bar_t * bar){ printf("Overloading with derived\n"); };
};
int main(){
derived_t derived;
zoo_t zoo;
derived.dostuff(&zoo);
}
I see it is doing what I mean, but I would like you to confirm that this is not just a coincidence.
What I mean is that I want C++ to resolve the method that "gets closer" to the specialized class zoo_t. In this case the first ancestor found is bar_t which determines that the derived_t class method is invoked. Is this the way C++ resolves overloaded methods when arguments are both specialized and base classes?
Upvotes: 1
Views: 1263
Reputation: 171127
First off, I see your functions are not virtual
. I will assume that's intended and leave virtual
out of discussion.
You normally don't overload a base class's member functions in a derived class; you hide them instead. Which means that base_t::dostuff
is not accessible through an object-accessing expression of type derived_t
. In other words, this won't compile:
int main()
{
derived_t derived;
foo_t foo;
derived.dostuff(&foo);
}
However, this will:
int main()
{
derived_t derived;
foo_t foo;
base_t& base = derived;
base.dostuff(&foo);
derived.base_t::dostuff(&foo);
}
This has other implications as well. For example the code below will print Defaulting to base
:
int main()
{
derived_t derived;
zoo_t zoo;
base_t& base = derived;
base.dostuff(&zoo);
}
To summarize - which function gets called is based on the type of the expression choosing the object (the expression to the left of .
or ->
), and that type only. That will always work that way, so if that's the behaviour you're after, you're fine.
If you want to really overload the inherited function instead of hiding it, you can use a using
declaration:
class derived_t: public base_t{
public:
void dostuff(bar_t * bar){ printf("Overloading with derived\n"); };
using bas_t::dostuff;
};
Then, the following code will work:
int main()
{
derived_t derived;
foo_t foo;
bar_t bar;
zoo_t zoo;
derived.dostuff(&foo); // calls base
derived.dostuff(&bar); // calls derived
derived.dostuff(&zoo); // calss derived
}
Upvotes: 3